|
|
1.1 root 1: /* Convert RTL to assembler code and output it, 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 is the final pass of the compiler. 22: It looks at the rtl code for a function and outputs assembler code. 23: 24: Call `final_start_function' to output the assembler code for function entry, 25: `final' to output assembler code for some RTL code, 26: `final_end_function' to output assembler code for function exit. 27: If a function is compiled in several pieces, each piece is 28: output separately with `final'. 29: 30: Some optimizations are also done at this level. 31: Move instructions that were made unnecessary by good register allocation 32: are detected and omitted from the output. (Though most of these 33: are removed by the last jump pass.) 34: 35: Instructions to set the condition codes are omitted when it can be 36: seen that the condition codes already had the desired values. 37: 38: In some cases it is sufficient if the inherited condition codes 39: have related values, but this may require the following insn 40: (the one that tests the condition codes) to be modified. 41: 42: The code for the function prologue and epilogue are generated 43: directly as assembler code by the macros FUNCTION_PROLOGUE and 44: FUNCTION_EPILOGUE. Those instructions never exist as rtl. */ 45: 46: #include "config.h" 1.1.1.7 ! root 47: #ifdef __STDC__ ! 48: #include <stdarg.h> ! 49: #else ! 50: #include <varargs.h> ! 51: #endif ! 52: #include <stdio.h> ! 53: #include <ctype.h> ! 54: 1.1.1.6 root 55: #include "tree.h" 1.1 root 56: #include "rtl.h" 57: #include "regs.h" 58: #include "insn-config.h" 1.1.1.4 root 59: #include "insn-flags.h" 1.1 root 60: #include "insn-attr.h" 61: #include "insn-codes.h" 62: #include "recog.h" 63: #include "conditions.h" 64: #include "flags.h" 65: #include "real.h" 66: #include "hard-reg-set.h" 1.1.1.4 root 67: #include "defaults.h" 68: #include "output.h" 1.1 root 69: 70: /* Get N_SLINE and N_SOL from stab.h if we can expect the file to exist. */ 1.1.1.2 root 71: #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 72: #if defined (USG) || defined (NO_STAB_H) 1.1 root 73: #include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */ 74: #else 75: #include <stab.h> /* On BSD, use the system's stab.h. */ 76: #endif /* not USG */ 1.1.1.2 root 77: #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */ 78: 79: #ifdef XCOFF_DEBUGGING_INFO 80: #include "xcoffout.h" 81: #endif 1.1 root 82: 83: /* .stabd code for line number. */ 84: #ifndef N_SLINE 85: #define N_SLINE 0x44 86: #endif 87: 88: /* .stabs code for included file name. */ 89: #ifndef N_SOL 90: #define N_SOL 0x84 91: #endif 92: 93: #ifndef INT_TYPE_SIZE 94: #define INT_TYPE_SIZE BITS_PER_WORD 95: #endif 96: 97: /* If we aren't using cc0, CC_STATUS_INIT shouldn't exist. So define a 98: null default for it to save conditionalization later. */ 99: #ifndef CC_STATUS_INIT 100: #define CC_STATUS_INIT 101: #endif 102: 103: /* How to start an assembler comment. */ 104: #ifndef ASM_COMMENT_START 105: #define ASM_COMMENT_START ";#" 106: #endif 107: 1.1.1.7 ! root 108: /* Is the given character a logical line separator for the assembler? */ ! 109: #ifndef IS_ASM_LOGICAL_LINE_SEPARATOR ! 110: #define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == ';') 1.1 root 111: #endif 112: 113: /* Nonzero means this function is a leaf function, with no function calls. 114: This variable exists to be examined in FUNCTION_PROLOGUE 115: and FUNCTION_EPILOGUE. Always zero, unless set by some action. */ 116: int leaf_function; 117: 118: /* Last insn processed by final_scan_insn. */ 119: static rtx debug_insn = 0; 120: 121: /* Line number of last NOTE. */ 122: static int last_linenum; 123: 1.1.1.6 root 124: /* Filename of last NOTE. */ 125: static char *last_filename; 126: 1.1 root 127: /* Number of basic blocks seen so far; 128: used if profile_block_flag is set. */ 129: static int count_basic_blocks; 130: 131: /* Nonzero while outputting an `asm' with operands. 132: This means that inconsistencies are the user's fault, so don't abort. 133: The precise value is the insn being output, to pass to error_for_asm. */ 134: static rtx this_is_asm_operands; 135: 136: /* Number of operands of this insn, for an `asm' with operands. */ 137: static int insn_noperands; 138: 139: /* Compare optimization flag. */ 140: 141: static rtx last_ignored_compare = 0; 142: 143: /* Flag indicating this insn is the start of a new basic block. */ 144: 145: static int new_block = 1; 146: 147: /* All the symbol-blocks (levels of scoping) in the compilation 148: are assigned sequence numbers in order of appearance of the 149: beginnings of the symbol-blocks. Both final and dbxout do this, 150: and assume that they will both give the same number to each block. 151: Final uses these sequence numbers to generate assembler label names 152: LBBnnn and LBEnnn for the beginning and end of the symbol-block. 1.1.1.4 root 153: Dbxout uses the sequence numbers to generate references to the same labels 1.1 root 154: from the dbx debugging information. 155: 156: Sdb records this level at the beginning of each function, 157: in order to find the current level when recursing down declarations. 158: It outputs the block beginning and endings 159: at the point in the asm file where the blocks would begin and end. */ 160: 161: int next_block_index; 162: 163: /* Assign a unique number to each insn that is output. 164: This can be used to generate unique local labels. */ 165: 166: static int insn_counter = 0; 167: 168: #ifdef HAVE_cc0 169: /* This variable contains machine-dependent flags (defined in tm.h) 170: set and examined by output routines 171: that describe how to interpret the condition codes properly. */ 172: 173: CC_STATUS cc_status; 174: 175: /* During output of an insn, this contains a copy of cc_status 176: from before the insn. */ 177: 178: CC_STATUS cc_prev_status; 179: #endif 180: 181: /* Indexed by hardware reg number, is 1 if that register is ever 182: used in the current function. 183: 184: In life_analysis, or in stupid_life_analysis, this is set 185: up to record the hard regs used explicitly. Reload adds 186: in the hard regs used for holding pseudo regs. Final uses 187: it to generate the code in the function prologue and epilogue 188: to save and restore registers as needed. */ 189: 190: char regs_ever_live[FIRST_PSEUDO_REGISTER]; 191: 192: /* Nonzero means current function must be given a frame pointer. 193: Set in stmt.c if anything is allocated on the stack there. 194: Set in reload1.c if anything is allocated on the stack there. */ 195: 196: int frame_pointer_needed; 197: 198: /* Assign unique numbers to labels generated for profiling. */ 199: 200: int profile_label_no; 201: 202: /* Length so far allocated in PENDING_BLOCKS. */ 203: 204: static int max_block_depth; 205: 206: /* Stack of sequence numbers of symbol-blocks of which we have seen the 207: beginning but not yet the end. Sequence numbers are assigned at 208: the beginning; this stack allows us to find the sequence number 209: of a block that is ending. */ 210: 211: static int *pending_blocks; 212: 213: /* Number of elements currently in use in PENDING_BLOCKS. */ 214: 215: static int block_depth; 216: 217: /* Nonzero if have enabled APP processing of our assembler output. */ 218: 219: static int app_on; 220: 221: /* If we are outputting an insn sequence, this contains the sequence rtx. 222: Zero otherwise. */ 223: 224: rtx final_sequence; 225: 1.1.1.6 root 226: #ifdef ASSEMBLER_DIALECT 227: 228: /* Number of the assembler dialect to use, starting at 0. */ 229: static int dialect_number; 230: #endif 231: 1.1 root 232: /* Indexed by line number, nonzero if there is a note for that line. */ 233: 234: static char *line_note_exists; 1.1.1.6 root 235: 236: /* Linked list to hold line numbers for each basic block. */ 237: 238: struct bb_list { 239: struct bb_list *next; /* pointer to next basic block */ 240: int line_num; /* line number */ 241: int file_label_num; /* LPBC<n> label # for stored filename */ 242: int func_label_num; /* LPBC<n> label # for stored function name */ 243: }; 244: 245: static struct bb_list *bb_head = 0; /* Head of basic block list */ 246: static struct bb_list **bb_tail = &bb_head; /* Ptr to store next bb ptr */ 247: static int bb_file_label_num = -1; /* Current label # for file */ 248: static int bb_func_label_num = -1; /* Current label # for func */ 249: 250: /* Linked list to hold the strings for each file and function name output. */ 251: 252: struct bb_str { 253: struct bb_str *next; /* pointer to next string */ 254: char *string; /* string */ 255: int label_num; /* label number */ 256: int length; /* string length */ 257: }; 258: 1.1.1.7 ! root 259: extern rtx peephole PROTO((rtx)); ! 260: 1.1.1.6 root 261: static struct bb_str *sbb_head = 0; /* Head of string list. */ 262: static struct bb_str **sbb_tail = &sbb_head; /* Ptr to store next bb str */ 263: static int sbb_label_num = 0; /* Last label used */ 264: 1.1.1.7 ! root 265: static int asm_insn_count PROTO((rtx)); ! 266: static void profile_function PROTO((FILE *)); ! 267: static void profile_after_prologue PROTO((FILE *)); ! 268: static void add_bb PROTO((FILE *)); ! 269: static int add_bb_string PROTO((char *, int)); ! 270: static void output_source_line PROTO((FILE *, rtx)); ! 271: static rtx walk_alter_subreg PROTO((rtx)); ! 272: static int alter_cond PROTO((rtx)); ! 273: static void output_operand PROTO((rtx, int)); ! 274: static void leaf_renumber_regs PROTO((rtx)); 1.1.1.6 root 275: 1.1.1.7 ! root 276: extern char *getpwd (); 1.1 root 277: 278: /* Initialize data in final at the beginning of a compilation. */ 279: 280: void 281: init_final (filename) 282: char *filename; 283: { 284: next_block_index = 2; 285: app_on = 0; 286: max_block_depth = 20; 287: pending_blocks = (int *) xmalloc (20 * sizeof *pending_blocks); 288: final_sequence = 0; 1.1.1.6 root 289: 290: #ifdef ASSEMBLER_DIALECT 291: dialect_number = ASSEMBLER_DIALECT; 292: #endif 1.1 root 293: } 294: 295: /* Called at end of source file, 296: to output the block-profiling table for this entire compilation. */ 297: 298: void 299: end_final (filename) 300: char *filename; 301: { 302: int i; 303: 304: if (profile_block_flag) 305: { 1.1.1.6 root 306: char name[20]; 307: int align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT); 1.1.1.7 ! root 308: int size = (POINTER_SIZE / BITS_PER_UNIT) * count_basic_blocks; 1.1.1.6 root 309: int rounded = size; 310: struct bb_list *ptr; 311: struct bb_str *sptr; 312: 313: rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1; 314: rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT) 315: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT)); 1.1 root 316: 317: data_section (); 318: 1.1.1.6 root 319: /* Output the main header, of 10 words: 1.1 root 320: 0: 1 if this file's initialized, else 0. 1.1.1.6 root 321: 1: address of file name (LPBX1). 322: 2: address of table of counts (LPBX2). 323: 3: number of counts in the table. 324: 4: always 0, for compatibility with Sun. 325: 326: The following are GNU extensions: 327: 328: 5: address of table of start addrs of basic blocks (LPBX3). 329: 6: Number of bytes in this header. 330: 7: address of table of function names (LPBX4). 331: 8: address of table of line numbers (LPBX5) or 0. 332: 9: address of table of file names (LPBX6) or 0. */ 333: 334: ASM_OUTPUT_ALIGN (asm_out_file, align); 1.1 root 335: 336: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 0); 1.1.1.6 root 337: /* zero word */ 1.1 root 338: assemble_integer (const0_rtx, UNITS_PER_WORD, 1); 1.1.1.6 root 339: 340: /* address of filename */ 1.1 root 341: ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 1); 342: assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1); 1.1.1.6 root 343: 344: /* address of count table */ 1.1 root 345: ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 2); 346: assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1); 1.1.1.6 root 347: 348: /* count of the # of basic blocks */ 1.1.1.4 root 349: assemble_integer (GEN_INT (count_basic_blocks), UNITS_PER_WORD, 1); 1.1.1.6 root 350: 351: /* zero word (link field) */ 1.1 root 352: assemble_integer (const0_rtx, UNITS_PER_WORD, 1); 1.1.1.6 root 353: 354: /* address of basic block start address table */ 1.1 root 355: ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 3); 356: assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1); 357: 1.1.1.6 root 358: /* byte count for extended structure. */ 359: assemble_integer (GEN_INT (10 * UNITS_PER_WORD), UNITS_PER_WORD, 1); 360: 361: /* address of function name table */ 362: ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 4); 363: assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1); 364: 365: /* address of line number and filename tables if debugging. */ 366: if (write_symbols != NO_DEBUG) 367: { 368: ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 5); 369: assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1); 370: ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 6); 371: assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1); 372: } 373: else 374: { 375: assemble_integer (const0_rtx, UNITS_PER_WORD, 1); 376: assemble_integer (const0_rtx, UNITS_PER_WORD, 1); 377: } 378: 379: /* Output the file name changing the suffix to .d for Sun tcov 380: compatibility. */ 1.1 root 381: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 1); 382: { 1.1.1.7 ! root 383: char *cwd = getpwd (); ! 384: int len = strlen (filename) + strlen (cwd) + 1; ! 385: char *data_file = (char *) alloca (len + 4); ! 386: ! 387: strcpy (data_file, cwd); ! 388: strcat (data_file, "/"); ! 389: strcat (data_file, filename); 1.1 root 390: strip_off_ending (data_file, len); 391: strcat (data_file, ".d"); 392: assemble_string (data_file, strlen (data_file) + 1); 393: } 394: 395: /* Make space for the table of counts. */ 1.1.1.6 root 396: if (flag_no_common || size == 0) 397: { 398: /* Realign data section. */ 399: ASM_OUTPUT_ALIGN (asm_out_file, align); 400: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 2); 401: if (size != 0) 402: assemble_zeros (size); 403: } 404: else 405: { 406: ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 2); 407: #ifdef ASM_OUTPUT_SHARED_LOCAL 408: if (flag_shared_data) 409: ASM_OUTPUT_SHARED_LOCAL (asm_out_file, name, size, rounded); 410: else 411: #endif 412: #ifdef ASM_OUTPUT_ALIGNED_LOCAL 1.1.1.7 ! root 413: ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, ! 414: BIGGEST_ALIGNMENT); 1.1.1.6 root 415: #else 416: ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded); 417: #endif 418: } 1.1 root 419: 1.1.1.6 root 420: /* Output any basic block strings */ 1.1 root 421: readonly_data_section (); 1.1.1.6 root 422: if (sbb_head) 423: { 424: ASM_OUTPUT_ALIGN (asm_out_file, align); 425: for (sptr = sbb_head; sptr != 0; sptr = sptr->next) 426: { 427: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBC", sptr->label_num); 428: assemble_string (sptr->string, sptr->length); 429: } 430: } 431: 432: /* Output the table of addresses. */ 1.1.1.4 root 433: /* Realign in new section */ 1.1.1.6 root 434: ASM_OUTPUT_ALIGN (asm_out_file, align); 1.1 root 435: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 3); 436: for (i = 0; i < count_basic_blocks; i++) 437: { 438: ASM_GENERATE_INTERNAL_LABEL (name, "LPB", i); 439: assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), 440: UNITS_PER_WORD, 1); 441: } 442: 1.1.1.6 root 443: /* Output the table of function names. */ 444: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 4); 445: for ((ptr = bb_head), (i = 0); ptr != 0; (ptr = ptr->next), i++) 446: { 447: if (ptr->func_label_num >= 0) 448: { 449: ASM_GENERATE_INTERNAL_LABEL (name, "LPBC", ptr->func_label_num); 450: assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), 451: UNITS_PER_WORD, 1); 452: } 453: else 454: assemble_integer (const0_rtx, UNITS_PER_WORD, 1); 455: } 456: 457: for ( ; i < count_basic_blocks; i++) 458: assemble_integer (const0_rtx, UNITS_PER_WORD, 1); 459: 460: if (write_symbols != NO_DEBUG) 461: { 462: /* Output the table of line numbers. */ 463: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 5); 464: for ((ptr = bb_head), (i = 0); ptr != 0; (ptr = ptr->next), i++) 465: assemble_integer (GEN_INT (ptr->line_num), UNITS_PER_WORD, 1); 466: 467: for ( ; i < count_basic_blocks; i++) 468: assemble_integer (const0_rtx, UNITS_PER_WORD, 1); 469: 470: /* Output the table of file names. */ 471: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 6); 472: for ((ptr = bb_head), (i = 0); ptr != 0; (ptr = ptr->next), i++) 473: { 474: if (ptr->file_label_num >= 0) 475: { 476: ASM_GENERATE_INTERNAL_LABEL (name, "LPBC", ptr->file_label_num); 477: assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), 478: UNITS_PER_WORD, 1); 479: } 480: else 481: assemble_integer (const0_rtx, UNITS_PER_WORD, 1); 482: } 483: 484: for ( ; i < count_basic_blocks; i++) 485: assemble_integer (const0_rtx, UNITS_PER_WORD, 1); 486: } 487: 1.1 root 488: /* End with the address of the table of addresses, 489: so we can find it easily, as the last word in the file's text. */ 490: ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 3); 491: assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1); 492: } 493: } 494: 495: /* Enable APP processing of subsequent output. 496: Used before the output from an `asm' statement. */ 497: 498: void 499: app_enable () 500: { 501: if (! app_on) 502: { 503: fprintf (asm_out_file, ASM_APP_ON); 504: app_on = 1; 505: } 506: } 507: 1.1.1.7 ! root 508: /* Disable APP processing of subsequent output. 1.1 root 509: Called from varasm.c before most kinds of output. */ 510: 511: void 512: app_disable () 513: { 514: if (app_on) 515: { 516: fprintf (asm_out_file, ASM_APP_OFF); 517: app_on = 0; 518: } 519: } 520: 521: /* Return the number of slots filled in the current 522: delayed branch sequence (we don't count the insn needing the 523: delay slot). Zero if not in a delayed branch sequence. */ 524: 525: #ifdef DELAY_SLOTS 526: int 527: dbr_sequence_length () 528: { 529: if (final_sequence != 0) 530: return XVECLEN (final_sequence, 0) - 1; 531: else 532: return 0; 533: } 534: #endif 535: 536: /* The next two pages contain routines used to compute the length of an insn 537: and to shorten branches. */ 538: 539: /* Arrays for insn lengths, and addresses. The latter is referenced by 540: `insn_current_length'. */ 541: 542: static short *insn_lengths; 543: int *insn_addresses; 544: 545: /* Address of insn being processed. Used by `insn_current_length'. */ 546: int insn_current_address; 547: 1.1.1.7 ! root 548: /* Indicate that branch shortening hasn't yet been done. */ 1.1 root 549: 550: void 551: init_insn_lengths () 552: { 553: insn_lengths = 0; 554: } 555: 556: /* Obtain the current length of an insn. If branch shortening has been done, 557: get its actual length. Otherwise, get its maximum length. */ 558: 559: int 560: get_attr_length (insn) 561: rtx insn; 562: { 563: #ifdef HAVE_ATTR_length 564: rtx body; 565: int i; 566: int length = 0; 567: 568: if (insn_lengths) 569: return insn_lengths[INSN_UID (insn)]; 570: else 571: switch (GET_CODE (insn)) 572: { 573: case NOTE: 574: case BARRIER: 575: case CODE_LABEL: 576: return 0; 577: 578: case CALL_INSN: 579: length = insn_default_length (insn); 580: break; 581: 582: case JUMP_INSN: 583: body = PATTERN (insn); 584: if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC) 585: { 586: /* This only takes room if jump tables go into the text section. */ 587: #if !defined(READONLY_DATA_SECTION) || defined(JUMP_TABLES_IN_TEXT_SECTION) 588: length = (XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC) 589: * GET_MODE_SIZE (GET_MODE (body))); 590: 591: /* Be pessimistic and assume worst-case alignment. */ 592: length += (GET_MODE_SIZE (GET_MODE (body)) - 1); 593: #else 594: return 0; 595: #endif 596: } 597: else 598: length = insn_default_length (insn); 599: break; 600: 601: case INSN: 602: body = PATTERN (insn); 603: if (GET_CODE (body) == USE || GET_CODE (body) == CLOBBER) 604: return 0; 605: 606: else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0) 1.1.1.6 root 607: length = asm_insn_count (body) * insn_default_length (insn); 1.1 root 608: else if (GET_CODE (body) == SEQUENCE) 609: for (i = 0; i < XVECLEN (body, 0); i++) 610: length += get_attr_length (XVECEXP (body, 0, i)); 611: else 612: length = insn_default_length (insn); 613: } 614: 615: #ifdef ADJUST_INSN_LENGTH 616: ADJUST_INSN_LENGTH (insn, length); 617: #endif 618: return length; 619: #else /* not HAVE_ATTR_length */ 620: return 0; 621: #endif /* not HAVE_ATTR_length */ 622: } 623: 624: /* Make a pass over all insns and compute their actual lengths by shortening 625: any branches of variable length if possible. */ 626: 627: /* Give a default value for the lowest address in a function. */ 628: 629: #ifndef FIRST_INSN_ADDRESS 630: #define FIRST_INSN_ADDRESS 0 631: #endif 632: 633: void 634: shorten_branches (first) 635: rtx first; 636: { 637: #ifdef HAVE_ATTR_length 638: rtx insn; 639: int something_changed = 1; 640: int max_uid = 0; 641: char *varying_length; 642: rtx body; 643: int uid; 644: 645: /* Compute maximum UID and allocate arrays. */ 646: for (insn = first; insn; insn = NEXT_INSN (insn)) 647: if (INSN_UID (insn) > max_uid) 648: max_uid = INSN_UID (insn); 649: 650: max_uid++; 651: insn_lengths = (short *) oballoc (max_uid * sizeof (short)); 652: insn_addresses = (int *) oballoc (max_uid * sizeof (int)); 653: varying_length = (char *) oballoc (max_uid * sizeof (char)); 654: 655: /* Compute initial lengths, addresses, and varying flags for each insn. */ 656: for (insn_current_address = FIRST_INSN_ADDRESS, insn = first; 657: insn != 0; 658: insn_current_address += insn_lengths[uid], insn = NEXT_INSN (insn)) 659: { 660: uid = INSN_UID (insn); 661: insn_addresses[uid] = insn_current_address; 662: insn_lengths[uid] = 0; 663: varying_length[uid] = 0; 664: 665: if (GET_CODE (insn) == NOTE || GET_CODE (insn) == BARRIER 666: || GET_CODE (insn) == CODE_LABEL) 667: continue; 668: 669: body = PATTERN (insn); 670: if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC) 671: { 672: /* This only takes room if read-only data goes into the text 673: section. */ 674: #if !defined(READONLY_DATA_SECTION) || defined(JUMP_TABLES_IN_TEXT_SECTION) 675: int unitsize = GET_MODE_SIZE (GET_MODE (body)); 676: 677: insn_lengths[uid] = (XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC) 678: * GET_MODE_SIZE (GET_MODE (body))); 679: 680: /* Account for possible alignment. */ 681: insn_lengths[uid] 682: += unitsize - (insn_current_address & (unitsize - 1)); 683: #else 684: ; 685: #endif 686: } 687: else if (asm_noperands (body) >= 0) 688: insn_lengths[uid] = asm_insn_count (body) * insn_default_length (insn); 689: else if (GET_CODE (body) == SEQUENCE) 690: { 691: int i; 1.1.1.4 root 692: int const_delay_slots; 693: #ifdef DELAY_SLOTS 694: const_delay_slots = const_num_delay_slots (XVECEXP (body, 0, 0)); 695: #else 696: const_delay_slots = 0; 697: #endif 1.1 root 698: /* Inside a delay slot sequence, we do not do any branch shortening 1.1.1.4 root 699: if the shortening could change the number of delay slots 700: of the branch. */ 1.1 root 701: for (i = 0; i < XVECLEN (body, 0); i++) 702: { 703: rtx inner_insn = XVECEXP (body, 0, i); 704: int inner_uid = INSN_UID (inner_insn); 705: int inner_length; 706: 707: if (asm_noperands (PATTERN (XVECEXP (body, 0, i))) >= 0) 708: inner_length = (asm_insn_count (PATTERN (inner_insn)) 709: * insn_default_length (inner_insn)); 710: else 711: inner_length = insn_default_length (inner_insn); 712: 713: insn_lengths[inner_uid] = inner_length; 1.1.1.4 root 714: if (const_delay_slots) 715: { 716: if ((varying_length[inner_uid] 717: = insn_variable_length_p (inner_insn)) != 0) 718: varying_length[uid] = 1; 719: insn_addresses[inner_uid] = (insn_current_address + 720: insn_lengths[uid]); 721: } 722: else 723: varying_length[inner_uid] = 0; 1.1 root 724: insn_lengths[uid] += inner_length; 725: } 726: } 727: else if (GET_CODE (body) != USE && GET_CODE (body) != CLOBBER) 728: { 729: insn_lengths[uid] = insn_default_length (insn); 730: varying_length[uid] = insn_variable_length_p (insn); 731: } 732: 733: /* If needed, do any adjustment. */ 734: #ifdef ADJUST_INSN_LENGTH 735: ADJUST_INSN_LENGTH (insn, insn_lengths[uid]); 736: #endif 737: } 738: 739: /* Now loop over all the insns finding varying length insns. For each, 740: get the current insn length. If it has changed, reflect the change. 741: When nothing changes for a full pass, we are done. */ 742: 743: while (something_changed) 744: { 745: something_changed = 0; 746: for (insn_current_address = FIRST_INSN_ADDRESS, insn = first; 747: insn != 0; 1.1.1.4 root 748: insn = NEXT_INSN (insn)) 1.1 root 749: { 750: int new_length; 1.1.1.5 root 751: int tmp_length; 1.1 root 752: 753: uid = INSN_UID (insn); 754: insn_addresses[uid] = insn_current_address; 755: if (! varying_length[uid]) 1.1.1.4 root 756: { 757: insn_current_address += insn_lengths[uid]; 758: continue; 759: } 760: if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE) 761: { 762: int i; 763: 764: body = PATTERN (insn); 765: new_length = 0; 766: for (i = 0; i < XVECLEN (body, 0); i++) 767: { 768: rtx inner_insn = XVECEXP (body, 0, i); 769: int inner_uid = INSN_UID (inner_insn); 770: int inner_length; 771: 772: insn_addresses[inner_uid] = insn_current_address; 1.1.1.5 root 773: 774: /* insn_current_length returns 0 for insns with a 775: non-varying length. */ 776: if (! varying_length[inner_uid]) 777: inner_length = insn_lengths[inner_uid]; 778: else 779: inner_length = insn_current_length (inner_insn); 780: 1.1.1.4 root 781: if (inner_length != insn_lengths[inner_uid]) 782: { 783: insn_lengths[inner_uid] = inner_length; 784: something_changed = 1; 785: } 786: insn_current_address += insn_lengths[inner_uid]; 787: new_length += inner_length; 788: } 789: } 790: else 791: { 792: new_length = insn_current_length (insn); 793: insn_current_address += new_length; 794: } 1.1.1.5 root 795: 796: #ifdef SHORTEN_WITH_ADJUST_INSN_LENGTH 797: #ifdef ADJUST_INSN_LENGTH 798: /* If needed, do any adjustment. */ 799: tmp_length = new_length; 800: ADJUST_INSN_LENGTH (insn, new_length); 801: insn_current_address += (new_length - tmp_length); 802: #endif 803: #endif 804: 1.1 root 805: if (new_length != insn_lengths[uid]) 806: { 807: insn_lengths[uid] = new_length; 808: something_changed = 1; 809: } 810: } 811: } 812: #endif /* HAVE_ATTR_length */ 813: } 814: 815: #ifdef HAVE_ATTR_length 816: /* Given the body of an INSN known to be generated by an ASM statement, return 817: the number of machine instructions likely to be generated for this insn. 818: This is used to compute its length. */ 819: 820: static int 821: asm_insn_count (body) 822: rtx body; 823: { 824: char *template; 825: int count = 1; 826: 1.1.1.7 ! root 827: if (GET_CODE (body) == ASM_INPUT) ! 828: template = XSTR (body, 0); ! 829: else ! 830: template = decode_asm_operands (body, NULL_PTR, NULL_PTR, ! 831: NULL_PTR, NULL_PTR); ! 832: ! 833: for ( ; *template; template++) ! 834: if (IS_ASM_LOGICAL_LINE_SEPARATOR(*template) || *template == '\n') 1.1 root 835: count++; 836: 837: return count; 838: } 839: #endif 840: 841: /* Output assembler code for the start of a function, 842: and initialize some of the variables in this file 843: for the new function. The label for the function and associated 844: assembler pseudo-ops have already been output in `assemble_start_function'. 845: 846: FIRST is the first insn of the rtl for the function being compiled. 847: FILE is the file to write assembler code to. 848: OPTIMIZE is nonzero if we should eliminate redundant 849: test and compare insns. */ 850: 851: void 852: final_start_function (first, file, optimize) 853: rtx first; 854: FILE *file; 855: int optimize; 856: { 857: block_depth = 0; 858: 859: this_is_asm_operands = 0; 860: 861: #ifdef NON_SAVING_SETJMP 862: /* A function that calls setjmp should save and restore all the 863: call-saved registers on a system where longjmp clobbers them. */ 864: if (NON_SAVING_SETJMP && current_function_calls_setjmp) 865: { 866: int i; 867: 868: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 869: if (!call_used_regs[i] && !call_fixed_regs[i]) 870: regs_ever_live[i] = 1; 871: } 872: #endif 873: 874: /* Initial line number is supposed to be output 875: before the function's prologue and label 876: so that the function's address will not appear to be 877: in the last statement of the preceding function. */ 878: if (NOTE_LINE_NUMBER (first) != NOTE_INSN_DELETED) 879: { 880: if (write_symbols == SDB_DEBUG) 881: /* For sdb, let's not, but say we did. 882: We need to set last_linenum for sdbout_function_begin, 883: but we can't have an actual line number before the .bf symbol. 884: (sdb_begin_function_line is not set, 885: and other compilers don't do it.) */ 886: last_linenum = NOTE_LINE_NUMBER (first); 1.1.1.2 root 887: #ifdef XCOFF_DEBUGGING_INFO 888: else if (write_symbols == XCOFF_DEBUG) 889: { 890: last_linenum = NOTE_LINE_NUMBER (first); 891: xcoffout_output_first_source_line (file, last_linenum); 892: } 893: #endif 1.1 root 894: else 895: output_source_line (file, first); 896: } 897: 898: #ifdef LEAF_REG_REMAP 899: if (leaf_function) 900: leaf_renumber_regs (first); 901: #endif 902: 903: /* The Sun386i and perhaps other machines don't work right 904: if the profiling code comes after the prologue. */ 905: #ifdef PROFILE_BEFORE_PROLOGUE 906: if (profile_flag) 907: profile_function (file); 908: #endif /* PROFILE_BEFORE_PROLOGUE */ 909: 910: #ifdef FUNCTION_PROLOGUE 911: /* First output the function prologue: code to set up the stack frame. */ 912: FUNCTION_PROLOGUE (file, get_frame_size ()); 913: #endif 914: 1.1.1.2 root 915: #if defined (SDB_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 916: if (write_symbols == SDB_DEBUG || write_symbols == XCOFF_DEBUG) 1.1 root 917: next_block_index = 1; 918: #endif 919: 1.1.1.4 root 920: /* If the machine represents the prologue as RTL, the profiling code must 921: be emitted when NOTE_INSN_PROLOGUE_END is scanned. */ 922: #ifdef HAVE_prologue 923: if (! HAVE_prologue) 924: #endif 925: profile_after_prologue (file); 926: 927: profile_label_no++; 1.1.1.6 root 928: 929: /* If we are doing basic block profiling, remember a printable version 930: of the function name. */ 931: if (profile_block_flag) 932: { 933: char *junk = "function"; 934: bb_func_label_num = 935: add_bb_string ((*decl_printable_name) (current_function_decl, &junk), FALSE); 936: } 1.1.1.4 root 937: } 938: 939: static void 940: profile_after_prologue (file) 941: FILE *file; 942: { 1.1 root 943: #ifdef FUNCTION_BLOCK_PROFILER 944: if (profile_block_flag) 945: { 946: FUNCTION_BLOCK_PROFILER (file, profile_label_no); 947: } 948: #endif /* FUNCTION_BLOCK_PROFILER */ 949: 950: #ifndef PROFILE_BEFORE_PROLOGUE 951: if (profile_flag) 952: profile_function (file); 953: #endif /* not PROFILE_BEFORE_PROLOGUE */ 954: } 955: 1.1.1.7 ! root 956: static void 1.1 root 957: profile_function (file) 958: FILE *file; 959: { 1.1.1.7 ! root 960: int align = MIN (BIGGEST_ALIGNMENT, POINTER_SIZE); 1.1 root 961: int sval = current_function_returns_struct; 962: int cxt = current_function_needs_context; 963: 964: data_section (); 965: ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT)); 966: ASM_OUTPUT_INTERNAL_LABEL (file, "LP", profile_label_no); 1.1.1.7 ! root 967: assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); 1.1 root 968: 969: text_section (); 970: 971: #ifdef STRUCT_VALUE_INCOMING_REGNUM 972: if (sval) 973: ASM_OUTPUT_REG_PUSH (file, STRUCT_VALUE_INCOMING_REGNUM); 974: #else 975: #ifdef STRUCT_VALUE_REGNUM 976: if (sval) 977: ASM_OUTPUT_REG_PUSH (file, STRUCT_VALUE_REGNUM); 978: #endif 979: #endif 980: 981: #if 0 982: #ifdef STATIC_CHAIN_INCOMING_REGNUM 983: if (cxt) 984: ASM_OUTPUT_REG_PUSH (file, STATIC_CHAIN_INCOMING_REGNUM); 985: #else 986: #ifdef STATIC_CHAIN_REGNUM 987: if (cxt) 988: ASM_OUTPUT_REG_PUSH (file, STATIC_CHAIN_REGNUM); 989: #endif 990: #endif 991: #endif /* 0 */ 992: 993: FUNCTION_PROFILER (file, profile_label_no); 994: 995: #if 0 996: #ifdef STATIC_CHAIN_INCOMING_REGNUM 997: if (cxt) 998: ASM_OUTPUT_REG_POP (file, STATIC_CHAIN_INCOMING_REGNUM); 999: #else 1000: #ifdef STATIC_CHAIN_REGNUM 1001: if (cxt) 1002: ASM_OUTPUT_REG_POP (file, STATIC_CHAIN_REGNUM); 1003: #endif 1004: #endif 1005: #endif /* 0 */ 1006: 1007: #ifdef STRUCT_VALUE_INCOMING_REGNUM 1008: if (sval) 1009: ASM_OUTPUT_REG_POP (file, STRUCT_VALUE_INCOMING_REGNUM); 1010: #else 1011: #ifdef STRUCT_VALUE_REGNUM 1012: if (sval) 1013: ASM_OUTPUT_REG_POP (file, STRUCT_VALUE_REGNUM); 1014: #endif 1015: #endif 1016: } 1017: 1018: /* Output assembler code for the end of a function. 1019: For clarity, args are same as those of `final_start_function' 1020: even though not all of them are needed. */ 1021: 1022: void 1023: final_end_function (first, file, optimize) 1024: rtx first; 1025: FILE *file; 1026: int optimize; 1027: { 1028: if (app_on) 1029: { 1030: fprintf (file, ASM_APP_OFF); 1031: app_on = 0; 1032: } 1033: 1034: #ifdef SDB_DEBUGGING_INFO 1035: if (write_symbols == SDB_DEBUG) 1036: sdbout_end_function (last_linenum); 1037: #endif 1038: 1.1.1.4 root 1039: #ifdef DWARF_DEBUGGING_INFO 1040: if (write_symbols == DWARF_DEBUG) 1041: dwarfout_end_function (); 1042: #endif 1043: 1.1.1.2 root 1044: #ifdef XCOFF_DEBUGGING_INFO 1045: if (write_symbols == XCOFF_DEBUG) 1046: xcoffout_end_function (file, last_linenum); 1047: #endif 1048: 1.1 root 1049: #ifdef FUNCTION_EPILOGUE 1050: /* Finally, output the function epilogue: 1051: code to restore the stack frame and return to the caller. */ 1052: FUNCTION_EPILOGUE (file, get_frame_size ()); 1053: #endif 1054: 1055: #ifdef SDB_DEBUGGING_INFO 1056: if (write_symbols == SDB_DEBUG) 1057: sdbout_end_epilogue (); 1058: #endif 1059: 1060: #ifdef DWARF_DEBUGGING_INFO 1061: if (write_symbols == DWARF_DEBUG) 1062: dwarfout_end_epilogue (); 1063: #endif 1064: 1.1.1.2 root 1065: #ifdef XCOFF_DEBUGGING_INFO 1066: if (write_symbols == XCOFF_DEBUG) 1067: xcoffout_end_epilogue (file); 1068: #endif 1069: 1.1.1.6 root 1070: bb_func_label_num = -1; /* not in function, nuke label # */ 1071: 1.1 root 1072: /* If FUNCTION_EPILOGUE is not defined, then the function body 1073: itself contains return instructions wherever needed. */ 1074: } 1075: 1.1.1.6 root 1076: /* Add a block to the linked list that remembers the current line/file/function 1077: for basic block profiling. Emit the label in front of the basic block and 1078: the instructions that increment the count field. */ 1079: 1080: static void 1081: add_bb (file) 1082: FILE *file; 1083: { 1084: struct bb_list *ptr = (struct bb_list *) permalloc (sizeof (struct bb_list)); 1085: 1086: /* Add basic block to linked list. */ 1087: ptr->next = 0; 1088: ptr->line_num = last_linenum; 1089: ptr->file_label_num = bb_file_label_num; 1090: ptr->func_label_num = bb_func_label_num; 1091: *bb_tail = ptr; 1092: bb_tail = &ptr->next; 1093: 1094: /* Enable the table of basic-block use counts 1095: to point at the code it applies to. */ 1096: ASM_OUTPUT_INTERNAL_LABEL (file, "LPB", count_basic_blocks); 1097: 1098: /* Before first insn of this basic block, increment the 1099: count of times it was entered. */ 1100: #ifdef BLOCK_PROFILER 1101: BLOCK_PROFILER (file, count_basic_blocks); 1102: CC_STATUS_INIT; 1103: #endif 1104: 1105: new_block = 0; 1106: count_basic_blocks++; 1107: } 1108: 1109: /* Add a string to be used for basic block profiling. */ 1110: 1111: static int 1112: add_bb_string (string, perm_p) 1113: char *string; 1114: int perm_p; 1115: { 1116: int len; 1117: struct bb_str *ptr = 0; 1118: 1119: if (!string) 1120: { 1121: string = "<unknown>"; 1122: perm_p = TRUE; 1123: } 1124: 1125: /* Allocate a new string if the current string isn't permanent. If 1126: the string is permanent search for the same string in other 1127: allocations. */ 1128: 1129: len = strlen (string) + 1; 1130: if (!perm_p) 1131: { 1132: char *p = (char *) permalloc (len); 1133: bcopy (string, p, len); 1134: string = p; 1135: } 1136: else 1137: for (ptr = sbb_head; ptr != (struct bb_str *)0; ptr = ptr->next) 1138: if (ptr->string == string) 1139: break; 1140: 1141: /* Allocate a new string block if we need to. */ 1142: if (!ptr) 1143: { 1144: ptr = (struct bb_str *) permalloc (sizeof (*ptr)); 1145: ptr->next = 0; 1146: ptr->length = len; 1147: ptr->label_num = sbb_label_num++; 1148: ptr->string = string; 1149: *sbb_tail = ptr; 1150: sbb_tail = &ptr->next; 1151: } 1152: 1153: return ptr->label_num; 1154: } 1155: 1156: 1.1 root 1157: /* Output assembler code for some insns: all or part of a function. 1158: For description of args, see `final_start_function', above. 1159: 1160: PRESCAN is 1 if we are not really outputting, 1161: just scanning as if we were outputting. 1162: Prescanning deletes and rearranges insns just like ordinary output. 1163: PRESCAN is -2 if we are outputting after having prescanned. 1164: In this case, don't try to delete or rearrange insns 1165: because that has already been done. 1166: Prescanning is done only on certain machines. */ 1167: 1168: void 1169: final (first, file, optimize, prescan) 1170: rtx first; 1171: FILE *file; 1172: int optimize; 1173: int prescan; 1174: { 1175: register rtx insn; 1176: int max_line = 0; 1177: 1178: last_ignored_compare = 0; 1179: new_block = 1; 1180: 1.1.1.4 root 1181: /* Make a map indicating which line numbers appear in this function. 1182: When producing SDB debugging info, delete troublesome line number 1183: notes from inlined functions in other files as well as duplicate 1184: line number notes. */ 1185: #ifdef SDB_DEBUGGING_INFO 1186: if (write_symbols == SDB_DEBUG) 1187: { 1188: rtx last = 0; 1189: for (insn = first; insn; insn = NEXT_INSN (insn)) 1190: if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0) 1191: { 1192: if ((RTX_INTEGRATED_P (insn) 1193: && strcmp (NOTE_SOURCE_FILE (insn), main_input_filename) != 0) 1194: || (last != 0 1195: && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last) 1196: && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last))) 1197: { 1198: NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; 1199: NOTE_SOURCE_FILE (insn) = 0; 1200: continue; 1201: } 1202: last = insn; 1203: if (NOTE_LINE_NUMBER (insn) > max_line) 1204: max_line = NOTE_LINE_NUMBER (insn); 1205: } 1206: } 1207: else 1208: #endif 1209: { 1210: for (insn = first; insn; insn = NEXT_INSN (insn)) 1211: if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > max_line) 1212: max_line = NOTE_LINE_NUMBER (insn); 1213: } 1.1 root 1214: 1215: line_note_exists = (char *) oballoc (max_line + 1); 1216: bzero (line_note_exists, max_line + 1); 1217: 1218: for (insn = first; insn; insn = NEXT_INSN (insn)) 1219: if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0) 1220: line_note_exists[NOTE_LINE_NUMBER (insn)] = 1; 1221: 1222: init_recog (); 1223: 1224: CC_STATUS_INIT; 1225: 1226: /* Output the insns. */ 1227: for (insn = NEXT_INSN (first); insn;) 1228: insn = final_scan_insn (insn, file, optimize, prescan, 0); 1229: 1230: /* Do basic-block profiling here 1231: if the last insn was a conditional branch. */ 1232: if (profile_block_flag && new_block) 1.1.1.6 root 1233: add_bb (file); 1.1 root 1234: } 1235: 1236: /* The final scan for one insn, INSN. 1237: Args are same as in `final', except that INSN 1238: is the insn being scanned. 1239: Value returned is the next insn to be scanned. 1240: 1241: NOPEEPHOLES is the flag to disallow peephole processing (currently 1242: used for within delayed branch sequence output). */ 1243: 1244: rtx 1245: final_scan_insn (insn, file, optimize, prescan, nopeepholes) 1246: rtx insn; 1247: FILE *file; 1248: int optimize; 1249: int prescan; 1250: int nopeepholes; 1251: { 1252: register int i; 1253: insn_counter++; 1254: 1255: /* Ignore deleted insns. These can occur when we split insns (due to a 1256: template of "#") while not optimizing. */ 1257: if (INSN_DELETED_P (insn)) 1258: return NEXT_INSN (insn); 1259: 1260: switch (GET_CODE (insn)) 1261: { 1262: case NOTE: 1263: if (prescan > 0) 1264: break; 1265: 1266: /* Align the beginning of a loop, for higher speed 1267: on certain machines. */ 1268: 1269: if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG && optimize > 0) 1270: { 1271: #ifdef ASM_OUTPUT_LOOP_ALIGN 1272: rtx next = next_nonnote_insn (insn); 1273: if (next && GET_CODE (next) == CODE_LABEL) 1274: { 1275: ASM_OUTPUT_LOOP_ALIGN (asm_out_file); 1276: } 1277: #endif 1278: break; 1279: } 1280: if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END) 1281: break; 1282: 1.1.1.4 root 1283: if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END) 1284: { 1285: #ifdef FUNCTION_END_PROLOGUE 1286: FUNCTION_END_PROLOGUE (file); 1287: #endif 1288: profile_after_prologue (file); 1289: break; 1290: } 1291: 1292: #ifdef FUNCTION_BEGIN_EPILOGUE 1293: if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG) 1294: { 1295: FUNCTION_BEGIN_EPILOGUE (file); 1296: break; 1297: } 1298: #endif 1299: 1.1 root 1300: if (write_symbols == NO_DEBUG) 1301: break; 1302: if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG) 1303: { 1304: #ifdef SDB_DEBUGGING_INFO 1305: if (write_symbols == SDB_DEBUG) 1306: sdbout_begin_function (last_linenum); 1307: #endif 1.1.1.2 root 1308: #ifdef XCOFF_DEBUGGING_INFO 1309: if (write_symbols == XCOFF_DEBUG) 1310: xcoffout_begin_function (file, last_linenum); 1311: #endif 1.1.1.4 root 1312: #ifdef DWARF_DEBUGGING_INFO 1313: if (write_symbols == DWARF_DEBUG) 1314: dwarfout_begin_function (); 1315: #endif 1.1 root 1316: break; 1317: } 1318: if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED) 1319: break; /* An insn that was "deleted" */ 1320: if (app_on) 1321: { 1322: fprintf (file, ASM_APP_OFF); 1323: app_on = 0; 1324: } 1325: if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG 1326: && (debug_info_level == DINFO_LEVEL_NORMAL 1.1.1.4 root 1327: || debug_info_level == DINFO_LEVEL_VERBOSE 1328: #ifdef DWARF_DEBUGGING_INFO 1329: || write_symbols == DWARF_DEBUG 1330: #endif 1331: ) 1332: ) 1.1 root 1333: { 1334: /* Beginning of a symbol-block. Assign it a sequence number 1335: and push the number onto the stack PENDING_BLOCKS. */ 1336: 1337: if (block_depth == max_block_depth) 1338: { 1339: /* PENDING_BLOCKS is full; make it longer. */ 1340: max_block_depth *= 2; 1341: pending_blocks 1342: = (int *) xrealloc (pending_blocks, 1343: max_block_depth * sizeof (int)); 1344: } 1345: pending_blocks[block_depth++] = next_block_index; 1346: 1347: /* Output debugging info about the symbol-block beginning. */ 1348: 1349: #ifdef SDB_DEBUGGING_INFO 1350: if (write_symbols == SDB_DEBUG) 1351: sdbout_begin_block (file, last_linenum, next_block_index); 1352: #endif 1.1.1.2 root 1353: #ifdef XCOFF_DEBUGGING_INFO 1354: if (write_symbols == XCOFF_DEBUG) 1355: xcoffout_begin_block (file, last_linenum, next_block_index); 1356: #endif 1.1 root 1357: #ifdef DBX_DEBUGGING_INFO 1358: if (write_symbols == DBX_DEBUG) 1359: ASM_OUTPUT_INTERNAL_LABEL (file, "LBB", next_block_index); 1360: #endif 1361: #ifdef DWARF_DEBUGGING_INFO 1362: if (write_symbols == DWARF_DEBUG && block_depth > 1) 1363: dwarfout_begin_block (next_block_index); 1364: #endif 1365: 1366: next_block_index++; 1367: } 1368: else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END 1369: && (debug_info_level == DINFO_LEVEL_NORMAL 1.1.1.4 root 1370: || debug_info_level == DINFO_LEVEL_VERBOSE 1371: #ifdef DWARF_DEBUGGING_INFO 1372: || write_symbols == DWARF_DEBUG 1373: #endif 1374: ) 1375: ) 1.1 root 1376: { 1377: /* End of a symbol-block. Pop its sequence number off 1378: PENDING_BLOCKS and output debugging info based on that. */ 1379: 1380: --block_depth; 1381: 1.1.1.2 root 1382: #ifdef XCOFF_DEBUGGING_INFO 1383: if (write_symbols == XCOFF_DEBUG && block_depth >= 0) 1384: xcoffout_end_block (file, last_linenum, pending_blocks[block_depth]); 1385: #endif 1.1 root 1386: #ifdef DBX_DEBUGGING_INFO 1387: if (write_symbols == DBX_DEBUG && block_depth >= 0) 1388: ASM_OUTPUT_INTERNAL_LABEL (file, "LBE", 1389: pending_blocks[block_depth]); 1390: #endif 1391: #ifdef SDB_DEBUGGING_INFO 1392: if (write_symbols == SDB_DEBUG && block_depth >= 0) 1.1.1.7 ! root 1393: sdbout_end_block (file, last_linenum, pending_blocks[block_depth]); 1.1 root 1394: #endif 1395: #ifdef DWARF_DEBUGGING_INFO 1396: if (write_symbols == DWARF_DEBUG && block_depth >= 1) 1397: dwarfout_end_block (pending_blocks[block_depth]); 1398: #endif 1399: } 1.1.1.4 root 1400: else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL 1401: && (debug_info_level == DINFO_LEVEL_NORMAL 1402: || debug_info_level == DINFO_LEVEL_VERBOSE)) 1403: { 1404: #ifdef DWARF_DEBUGGING_INFO 1405: if (write_symbols == DWARF_DEBUG) 1406: dwarfout_label (insn); 1407: #endif 1408: } 1.1 root 1409: else if (NOTE_LINE_NUMBER (insn) > 0) 1410: /* This note is a line-number. */ 1411: { 1412: register rtx note; 1413: 1414: #if 0 /* This is what we used to do. */ 1415: output_source_line (file, insn); 1416: #endif 1417: int note_after = 0; 1418: 1419: /* If there is anything real after this note, 1420: output it. If another line note follows, omit this one. */ 1421: for (note = NEXT_INSN (insn); note; note = NEXT_INSN (note)) 1422: { 1423: if (GET_CODE (note) != NOTE && GET_CODE (note) != CODE_LABEL) 1424: break; 1.1.1.3 root 1425: /* These types of notes can be significant 1.1.1.4 root 1426: so make sure the preceding line number stays. */ 1.1.1.3 root 1427: else if (GET_CODE (note) == NOTE 1428: && (NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_BEG 1429: || NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_END 1430: || NOTE_LINE_NUMBER (note) == NOTE_INSN_FUNCTION_BEG)) 1431: break; 1.1 root 1432: else if (GET_CODE (note) == NOTE && NOTE_LINE_NUMBER (note) > 0) 1433: { 1.1.1.3 root 1434: /* Another line note follows; we can delete this note 1435: if no intervening line numbers have notes elsewhere. */ 1.1 root 1436: int num; 1437: for (num = NOTE_LINE_NUMBER (insn) + 1; 1438: num < NOTE_LINE_NUMBER (note); 1439: num++) 1440: if (line_note_exists[num]) 1441: break; 1442: 1.1.1.4 root 1443: if (num >= NOTE_LINE_NUMBER (note)) 1.1 root 1444: note_after = 1; 1445: break; 1446: } 1447: } 1448: 1449: /* Output this line note 1450: if it is the first or the last line note in a row. */ 1451: if (!note_after) 1452: output_source_line (file, insn); 1453: } 1454: break; 1455: 1456: case BARRIER: 1457: #ifdef ASM_OUTPUT_ALIGN_CODE 1.1.1.4 root 1458: /* Don't litter the assembler output with needless alignments. A 1459: BARRIER will be placed at the end of every function if HAVE_epilogue 1460: is true. */ 1461: if (NEXT_INSN (insn)) 1462: ASM_OUTPUT_ALIGN_CODE (file); 1.1 root 1463: #endif 1464: break; 1465: 1466: case CODE_LABEL: 1467: CC_STATUS_INIT; 1468: if (prescan > 0) 1469: break; 1470: new_block = 1; 1471: #ifdef SDB_DEBUGGING_INFO 1472: if (write_symbols == SDB_DEBUG && LABEL_NAME (insn)) 1473: sdbout_label (insn); 1474: #endif 1475: #ifdef DWARF_DEBUGGING_INFO 1476: if (write_symbols == DWARF_DEBUG && LABEL_NAME (insn)) 1477: dwarfout_label (insn); 1478: #endif 1479: if (app_on) 1480: { 1481: fprintf (file, ASM_APP_OFF); 1482: app_on = 0; 1483: } 1484: if (NEXT_INSN (insn) != 0 1485: && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN) 1486: { 1487: rtx nextbody = PATTERN (NEXT_INSN (insn)); 1488: 1489: /* If this label is followed by a jump-table, 1490: make sure we put the label in the read-only section. Also 1491: possibly write the label and jump table together. */ 1492: 1493: if (GET_CODE (nextbody) == ADDR_VEC 1494: || GET_CODE (nextbody) == ADDR_DIFF_VEC) 1495: { 1496: #ifndef JUMP_TABLES_IN_TEXT_SECTION 1497: readonly_data_section (); 1.1.1.4 root 1498: #ifdef READONLY_DATA_SECTION 1499: ASM_OUTPUT_ALIGN (file, 1500: exact_log2 (BIGGEST_ALIGNMENT 1501: / BITS_PER_UNIT)); 1502: #endif /* READONLY_DATA_SECTION */ 1503: #else /* JUMP_TABLES_IN_TEXT_SECTION */ 1.1 root 1504: text_section (); 1.1.1.4 root 1505: #endif /* JUMP_TABLES_IN_TEXT_SECTION */ 1.1 root 1506: #ifdef ASM_OUTPUT_CASE_LABEL 1507: ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn), 1508: NEXT_INSN (insn)); 1509: #else 1510: ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn)); 1511: #endif 1512: break; 1513: } 1514: } 1515: 1516: ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn)); 1517: break; 1518: 1519: default: 1520: { 1521: register rtx body = PATTERN (insn); 1522: int insn_code_number; 1523: char *template; 1524: rtx note; 1525: 1526: /* An INSN, JUMP_INSN or CALL_INSN. 1527: First check for special kinds that recog doesn't recognize. */ 1528: 1529: if (GET_CODE (body) == USE /* These are just declarations */ 1530: || GET_CODE (body) == CLOBBER) 1531: break; 1532: 1533: #ifdef HAVE_cc0 1534: /* If there is a REG_CC_SETTER note on this insn, it means that 1535: the setting of the condition code was done in the delay slot 1536: of the insn that branched here. So recover the cc status 1537: from the insn that set it. */ 1538: 1.1.1.4 root 1539: note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX); 1.1 root 1540: if (note) 1541: { 1542: NOTICE_UPDATE_CC (PATTERN (XEXP (note, 0)), XEXP (note, 0)); 1543: cc_prev_status = cc_status; 1544: } 1545: #endif 1546: 1547: /* Detect insns that are really jump-tables 1548: and output them as such. */ 1549: 1550: if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC) 1551: { 1552: register int vlen, idx; 1553: 1554: if (prescan > 0) 1555: break; 1556: 1557: if (app_on) 1558: { 1559: fprintf (file, ASM_APP_OFF); 1560: app_on = 0; 1561: } 1562: 1563: vlen = XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC); 1564: for (idx = 0; idx < vlen; idx++) 1565: { 1566: if (GET_CODE (body) == ADDR_VEC) 1.1.1.4 root 1567: { 1568: #ifdef ASM_OUTPUT_ADDR_VEC_ELT 1569: ASM_OUTPUT_ADDR_VEC_ELT 1570: (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0))); 1571: #else 1572: abort (); 1573: #endif 1574: } 1.1 root 1575: else 1.1.1.4 root 1576: { 1577: #ifdef ASM_OUTPUT_ADDR_DIFF_ELT 1578: ASM_OUTPUT_ADDR_DIFF_ELT 1579: (file, 1580: CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)), 1581: CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0))); 1582: #else 1583: abort (); 1584: #endif 1585: } 1.1 root 1586: } 1587: #ifdef ASM_OUTPUT_CASE_END 1588: ASM_OUTPUT_CASE_END (file, 1589: CODE_LABEL_NUMBER (PREV_INSN (insn)), 1590: insn); 1591: #endif 1592: 1593: text_section (); 1594: 1595: break; 1596: } 1597: 1598: /* Do basic-block profiling when we reach a new block. 1599: Done here to avoid jump tables. */ 1600: if (profile_block_flag && new_block) 1.1.1.6 root 1601: add_bb (file); 1.1 root 1602: 1603: if (GET_CODE (body) == ASM_INPUT) 1604: { 1605: /* There's no telling what that did to the condition codes. */ 1606: CC_STATUS_INIT; 1607: if (prescan > 0) 1608: break; 1609: if (! app_on) 1610: { 1611: fprintf (file, ASM_APP_ON); 1612: app_on = 1; 1613: } 1614: fprintf (asm_out_file, "\t%s\n", XSTR (body, 0)); 1615: break; 1616: } 1617: 1618: /* Detect `asm' construct with operands. */ 1619: if (asm_noperands (body) >= 0) 1620: { 1621: int noperands = asm_noperands (body); 1.1.1.7 ! root 1622: rtx *ops = (rtx *) alloca (noperands * sizeof (rtx)); 1.1 root 1623: char *string; 1624: 1625: /* There's no telling what that did to the condition codes. */ 1626: CC_STATUS_INIT; 1627: if (prescan > 0) 1628: break; 1629: 1630: if (! app_on) 1631: { 1632: fprintf (file, ASM_APP_ON); 1633: app_on = 1; 1634: } 1635: 1636: /* Get out the operand values. */ 1.1.1.4 root 1637: string = decode_asm_operands (body, ops, NULL_PTR, 1638: NULL_PTR, NULL_PTR); 1.1 root 1639: /* Inhibit aborts on what would otherwise be compiler bugs. */ 1640: insn_noperands = noperands; 1641: this_is_asm_operands = insn; 1.1.1.7 ! root 1642: 1.1 root 1643: /* Output the insn using them. */ 1644: output_asm_insn (string, ops); 1645: this_is_asm_operands = 0; 1646: break; 1647: } 1648: 1649: if (prescan <= 0 && app_on) 1650: { 1651: fprintf (file, ASM_APP_OFF); 1652: app_on = 0; 1653: } 1654: 1655: if (GET_CODE (body) == SEQUENCE) 1656: { 1657: /* A delayed-branch sequence */ 1658: register int i; 1659: rtx next; 1660: 1661: if (prescan > 0) 1662: break; 1663: final_sequence = body; 1664: 1665: /* The first insn in this SEQUENCE might be a JUMP_INSN that will 1666: force the restoration of a comparison that was previously 1667: thought unnecessary. If that happens, cancel this sequence 1668: and cause that insn to be restored. */ 1669: 1670: next = final_scan_insn (XVECEXP (body, 0, 0), file, 0, prescan, 1); 1671: if (next != XVECEXP (body, 0, 1)) 1672: { 1673: final_sequence = 0; 1674: return next; 1675: } 1676: 1677: for (i = 1; i < XVECLEN (body, 0); i++) 1678: final_scan_insn (XVECEXP (body, 0, i), file, 0, prescan, 1); 1679: #ifdef DBR_OUTPUT_SEQEND 1680: DBR_OUTPUT_SEQEND (file); 1681: #endif 1682: final_sequence = 0; 1683: 1684: /* If the insn requiring the delay slot was a CALL_INSN, the 1685: insns in the delay slot are actually executed before the 1686: called function. Hence we don't preserve any CC-setting 1687: actions in these insns and the CC must be marked as being 1688: clobbered by the function. */ 1689: if (GET_CODE (XVECEXP (body, 0, 0)) == CALL_INSN) 1690: CC_STATUS_INIT; 1.1.1.3 root 1691: 1692: /* Following a conditional branch sequence, we have a new basic 1693: block. */ 1694: if (profile_block_flag) 1695: { 1696: rtx insn = XVECEXP (body, 0, 0); 1697: rtx body = PATTERN (insn); 1698: 1699: if ((GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET 1700: && GET_CODE (SET_SRC (body)) != LABEL_REF) 1701: || (GET_CODE (insn) == JUMP_INSN 1702: && GET_CODE (body) == PARALLEL 1703: && GET_CODE (XVECEXP (body, 0, 0)) == SET 1704: && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF)) 1705: new_block = 1; 1706: } 1.1 root 1707: break; 1708: } 1709: 1710: /* We have a real machine instruction as rtl. */ 1711: 1712: body = PATTERN (insn); 1713: 1714: #ifdef HAVE_cc0 1715: /* Check for redundant test and compare instructions 1716: (when the condition codes are already set up as desired). 1717: This is done only when optimizing; if not optimizing, 1718: it should be possible for the user to alter a variable 1719: with the debugger in between statements 1720: and the next statement should reexamine the variable 1721: to compute the condition codes. */ 1722: 1723: if (optimize 1724: && GET_CODE (body) == SET 1725: && GET_CODE (SET_DEST (body)) == CC0 1726: && insn != last_ignored_compare) 1727: { 1728: if (GET_CODE (SET_SRC (body)) == SUBREG) 1729: SET_SRC (body) = alter_subreg (SET_SRC (body)); 1730: else if (GET_CODE (SET_SRC (body)) == COMPARE) 1731: { 1732: if (GET_CODE (XEXP (SET_SRC (body), 0)) == SUBREG) 1733: XEXP (SET_SRC (body), 0) 1734: = alter_subreg (XEXP (SET_SRC (body), 0)); 1735: if (GET_CODE (XEXP (SET_SRC (body), 1)) == SUBREG) 1736: XEXP (SET_SRC (body), 1) 1737: = alter_subreg (XEXP (SET_SRC (body), 1)); 1738: } 1739: if ((cc_status.value1 != 0 1740: && rtx_equal_p (SET_SRC (body), cc_status.value1)) 1741: || (cc_status.value2 != 0 1742: && rtx_equal_p (SET_SRC (body), cc_status.value2))) 1743: { 1744: /* Don't delete insn if it has an addressing side-effect. */ 1745: if (! FIND_REG_INC_NOTE (insn, 0) 1746: /* or if anything in it is volatile. */ 1747: && ! volatile_refs_p (PATTERN (insn))) 1748: { 1749: /* We don't really delete the insn; just ignore it. */ 1750: last_ignored_compare = insn; 1751: break; 1752: } 1753: } 1754: } 1755: #endif 1756: 1.1.1.3 root 1757: /* Following a conditional branch, we have a new basic block. 1758: But if we are inside a sequence, the new block starts after the 1759: last insn of the sequence. */ 1760: if (profile_block_flag && final_sequence == 0 1761: && ((GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET 1762: && GET_CODE (SET_SRC (body)) != LABEL_REF) 1763: || (GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == PARALLEL 1764: && GET_CODE (XVECEXP (body, 0, 0)) == SET 1765: && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF))) 1.1 root 1766: new_block = 1; 1767: 1768: #ifndef STACK_REGS 1769: /* Don't bother outputting obvious no-ops, even without -O. 1770: This optimization is fast and doesn't interfere with debugging. 1771: Don't do this if the insn is in a delay slot, since this 1772: will cause an improper number of delay insns to be written. */ 1773: if (final_sequence == 0 1774: && prescan >= 0 1775: && GET_CODE (insn) == INSN && GET_CODE (body) == SET 1776: && GET_CODE (SET_SRC (body)) == REG 1777: && GET_CODE (SET_DEST (body)) == REG 1778: && REGNO (SET_SRC (body)) == REGNO (SET_DEST (body))) 1779: break; 1780: #endif 1781: 1782: #ifdef HAVE_cc0 1783: /* If this is a conditional branch, maybe modify it 1784: if the cc's are in a nonstandard state 1785: so that it accomplishes the same thing that it would 1786: do straightforwardly if the cc's were set up normally. */ 1787: 1788: if (cc_status.flags != 0 1789: && GET_CODE (insn) == JUMP_INSN 1790: && GET_CODE (body) == SET 1791: && SET_DEST (body) == pc_rtx 1792: && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE 1793: /* This is done during prescan; it is not done again 1794: in final scan when prescan has been done. */ 1795: && prescan >= 0) 1796: { 1797: /* This function may alter the contents of its argument 1798: and clear some of the cc_status.flags bits. 1799: It may also return 1 meaning condition now always true 1800: or -1 meaning condition now always false 1801: or 2 meaning condition nontrivial but altered. */ 1802: register int result = alter_cond (XEXP (SET_SRC (body), 0)); 1803: /* If condition now has fixed value, replace the IF_THEN_ELSE 1804: with its then-operand or its else-operand. */ 1805: if (result == 1) 1806: SET_SRC (body) = XEXP (SET_SRC (body), 1); 1807: if (result == -1) 1808: SET_SRC (body) = XEXP (SET_SRC (body), 2); 1809: 1810: /* The jump is now either unconditional or a no-op. 1811: If it has become a no-op, don't try to output it. 1812: (It would not be recognized.) */ 1813: if (SET_SRC (body) == pc_rtx) 1814: { 1815: PUT_CODE (insn, NOTE); 1816: NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; 1817: NOTE_SOURCE_FILE (insn) = 0; 1818: break; 1819: } 1820: else if (GET_CODE (SET_SRC (body)) == RETURN) 1821: /* Replace (set (pc) (return)) with (return). */ 1822: PATTERN (insn) = body = SET_SRC (body); 1823: 1824: /* Rerecognize the instruction if it has changed. */ 1825: if (result != 0) 1826: INSN_CODE (insn) = -1; 1827: } 1828: 1829: /* Make same adjustments to instructions that examine the 1830: condition codes without jumping (if this machine has them). */ 1831: 1832: if (cc_status.flags != 0 1833: && GET_CODE (body) == SET) 1834: { 1835: switch (GET_CODE (SET_SRC (body))) 1836: { 1837: case GTU: 1838: case GT: 1839: case LTU: 1840: case LT: 1841: case GEU: 1842: case GE: 1843: case LEU: 1844: case LE: 1845: case EQ: 1846: case NE: 1847: { 1848: register int result; 1849: if (XEXP (SET_SRC (body), 0) != cc0_rtx) 1850: break; 1851: result = alter_cond (SET_SRC (body)); 1852: if (result == 1) 1853: validate_change (insn, &SET_SRC (body), const_true_rtx, 0); 1854: else if (result == -1) 1855: validate_change (insn, &SET_SRC (body), const0_rtx, 0); 1856: else if (result == 2) 1857: INSN_CODE (insn) = -1; 1858: } 1859: } 1860: } 1861: #endif 1862: 1863: /* Do machine-specific peephole optimizations if desired. */ 1864: 1865: if (optimize && !flag_no_peephole && !nopeepholes) 1866: { 1867: rtx next = peephole (insn); 1868: /* When peepholing, if there were notes within the peephole, 1869: emit them before the peephole. */ 1870: if (next != 0 && next != NEXT_INSN (insn)) 1871: { 1872: rtx prev = PREV_INSN (insn); 1873: rtx note; 1874: 1875: for (note = NEXT_INSN (insn); note != next; 1876: note = NEXT_INSN (note)) 1877: final_scan_insn (note, file, optimize, prescan, nopeepholes); 1878: 1879: /* In case this is prescan, put the notes 1880: in proper position for later rescan. */ 1881: note = NEXT_INSN (insn); 1882: PREV_INSN (note) = prev; 1883: NEXT_INSN (prev) = note; 1884: NEXT_INSN (PREV_INSN (next)) = insn; 1885: PREV_INSN (insn) = PREV_INSN (next); 1886: NEXT_INSN (insn) = next; 1887: PREV_INSN (next) = insn; 1888: } 1889: 1890: /* PEEPHOLE might have changed this. */ 1891: body = PATTERN (insn); 1892: } 1893: 1894: /* Try to recognize the instruction. 1895: If successful, verify that the operands satisfy the 1896: constraints for the instruction. Crash if they don't, 1897: since `reload' should have changed them so that they do. */ 1898: 1899: insn_code_number = recog_memoized (insn); 1900: insn_extract (insn); 1901: for (i = 0; i < insn_n_operands[insn_code_number]; i++) 1902: { 1903: if (GET_CODE (recog_operand[i]) == SUBREG) 1904: recog_operand[i] = alter_subreg (recog_operand[i]); 1.1.1.6 root 1905: else if (GET_CODE (recog_operand[i]) == PLUS 1906: || GET_CODE (recog_operand[i]) == MULT) 1907: recog_operand[i] = walk_alter_subreg (recog_operand[i]); 1.1 root 1908: } 1909: 1.1.1.5 root 1910: for (i = 0; i < insn_n_dups[insn_code_number]; i++) 1911: { 1912: if (GET_CODE (*recog_dup_loc[i]) == SUBREG) 1913: *recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]); 1.1.1.6 root 1914: else if (GET_CODE (*recog_dup_loc[i]) == PLUS 1915: || GET_CODE (*recog_dup_loc[i]) == MULT) 1916: *recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]); 1.1.1.5 root 1917: } 1918: 1.1 root 1919: #ifdef REGISTER_CONSTRAINTS 1920: if (! constrain_operands (insn_code_number, 1)) 1921: fatal_insn_not_found (insn); 1922: #endif 1923: 1924: /* Some target machines need to prescan each insn before 1925: it is output. */ 1926: 1927: #ifdef FINAL_PRESCAN_INSN 1928: FINAL_PRESCAN_INSN (insn, recog_operand, 1929: insn_n_operands[insn_code_number]); 1930: #endif 1931: 1932: #ifdef HAVE_cc0 1933: cc_prev_status = cc_status; 1934: 1935: /* Update `cc_status' for this instruction. 1936: The instruction's output routine may change it further. 1937: If the output routine for a jump insn needs to depend 1938: on the cc status, it should look at cc_prev_status. */ 1939: 1940: NOTICE_UPDATE_CC (body, insn); 1941: #endif 1942: 1943: debug_insn = insn; 1944: 1945: /* If the proper template needs to be chosen by some C code, 1946: run that code and get the real template. */ 1947: 1948: template = insn_template[insn_code_number]; 1949: if (template == 0) 1950: { 1951: template = (*insn_outfun[insn_code_number]) (recog_operand, insn); 1952: 1953: /* If the C code returns 0, it means that it is a jump insn 1954: which follows a deleted test insn, and that test insn 1955: needs to be reinserted. */ 1956: if (template == 0) 1957: { 1958: if (prev_nonnote_insn (insn) != last_ignored_compare) 1959: abort (); 1960: new_block = 0; 1961: return prev_nonnote_insn (insn); 1962: } 1963: } 1964: 1965: /* If the template is the string "#", it means that this insn must 1966: be split. */ 1967: if (template[0] == '#' && template[1] == '\0') 1968: { 1969: rtx new = try_split (body, insn, 0); 1970: 1971: /* If we didn't split the insn, go away. */ 1972: if (new == insn && PATTERN (new) == body) 1973: abort (); 1974: 1975: new_block = 0; 1976: return new; 1977: } 1978: 1979: if (prescan > 0) 1980: break; 1981: 1982: /* Output assembler code from the template. */ 1983: 1984: output_asm_insn (template, recog_operand); 1985: 1986: #if 0 1987: /* It's not at all clear why we did this and doing so interferes 1988: with tests we'd like to do to use REG_WAS_0 notes, so let's try 1989: with this out. */ 1990: 1991: /* Mark this insn as having been output. */ 1992: INSN_DELETED_P (insn) = 1; 1993: #endif 1994: 1995: debug_insn = 0; 1996: } 1997: } 1998: return NEXT_INSN (insn); 1999: } 2000: 2001: /* Output debugging info to the assembler file FILE 2002: based on the NOTE-insn INSN, assumed to be a line number. */ 2003: 2004: static void 2005: output_source_line (file, insn) 2006: FILE *file; 2007: rtx insn; 2008: { 2009: register char *filename = NOTE_SOURCE_FILE (insn); 2010: 1.1.1.6 root 2011: /* Remember filename for basic block profiling. 2012: Filenames are allocated on the permanent obstack 2013: or are passed in ARGV, so we don't have to save 2014: the string. */ 2015: 2016: if (profile_block_flag && last_filename != filename) 2017: bb_file_label_num = add_bb_string (filename, TRUE); 2018: 2019: last_filename = filename; 1.1 root 2020: last_linenum = NOTE_LINE_NUMBER (insn); 2021: 2022: if (write_symbols != NO_DEBUG) 2023: { 2024: #ifdef SDB_DEBUGGING_INFO 2025: if (write_symbols == SDB_DEBUG 2026: #if 0 /* People like having line numbers even in wrong file! */ 2027: /* COFF can't handle multiple source files--lose, lose. */ 2028: && !strcmp (filename, main_input_filename) 2029: #endif 2030: /* COFF relative line numbers must be positive. */ 2031: && last_linenum > sdb_begin_function_line) 2032: { 2033: #ifdef ASM_OUTPUT_SOURCE_LINE 2034: ASM_OUTPUT_SOURCE_LINE (file, last_linenum); 2035: #else 2036: fprintf (file, "\t.ln\t%d\n", 2037: ((sdb_begin_function_line > -1) 2038: ? last_linenum - sdb_begin_function_line : 1)); 2039: #endif 2040: } 2041: #endif 2042: 1.1.1.7 ! root 2043: #if defined (DBX_DEBUGGING_INFO) ! 2044: if (write_symbols == DBX_DEBUG) 1.1.1.4 root 2045: dbxout_source_line (file, filename, NOTE_LINE_NUMBER (insn)); 1.1.1.7 ! root 2046: #endif ! 2047: ! 2048: #if defined (XCOFF_DEBUGGING_INFO) ! 2049: if (write_symbols == XCOFF_DEBUG) ! 2050: xcoffout_source_line (file, filename, insn); ! 2051: #endif 1.1 root 2052: 2053: #ifdef DWARF_DEBUGGING_INFO 2054: if (write_symbols == DWARF_DEBUG) 2055: dwarfout_line (filename, NOTE_LINE_NUMBER (insn)); 2056: #endif 2057: } 2058: } 2059: 2060: /* If X is a SUBREG, replace it with a REG or a MEM, 2061: based on the thing it is a subreg of. */ 2062: 2063: rtx 2064: alter_subreg (x) 2065: register rtx x; 2066: { 2067: register rtx y = SUBREG_REG (x); 2068: if (GET_CODE (y) == SUBREG) 2069: y = alter_subreg (y); 2070: 2071: if (GET_CODE (y) == REG) 2072: { 2073: /* If the containing reg really gets a hard reg, so do we. */ 2074: PUT_CODE (x, REG); 2075: REGNO (x) = REGNO (y) + SUBREG_WORD (x); 2076: } 2077: else if (GET_CODE (y) == MEM) 2078: { 2079: register int offset = SUBREG_WORD (x) * UNITS_PER_WORD; 2080: #if BYTES_BIG_ENDIAN 2081: offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))) 2082: - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (y)))); 2083: #endif 2084: PUT_CODE (x, MEM); 2085: MEM_VOLATILE_P (x) = MEM_VOLATILE_P (y); 2086: XEXP (x, 0) = plus_constant (XEXP (y, 0), offset); 2087: } 2088: 2089: return x; 2090: } 2091: 2092: /* Do alter_subreg on all the SUBREGs contained in X. */ 2093: 2094: static rtx 2095: walk_alter_subreg (x) 2096: rtx x; 2097: { 2098: switch (GET_CODE (x)) 2099: { 2100: case PLUS: 2101: case MULT: 2102: XEXP (x, 0) = walk_alter_subreg (XEXP (x, 0)); 2103: XEXP (x, 1) = walk_alter_subreg (XEXP (x, 1)); 2104: break; 2105: 2106: case MEM: 2107: XEXP (x, 0) = walk_alter_subreg (XEXP (x, 0)); 2108: break; 2109: 2110: case SUBREG: 2111: return alter_subreg (x); 2112: } 2113: 2114: return x; 2115: } 2116: 2117: #ifdef HAVE_cc0 2118: 2119: /* Given BODY, the body of a jump instruction, alter the jump condition 2120: as required by the bits that are set in cc_status.flags. 2121: Not all of the bits there can be handled at this level in all cases. 2122: 2123: The value is normally 0. 2124: 1 means that the condition has become always true. 2125: -1 means that the condition has become always false. 2126: 2 means that COND has been altered. */ 2127: 2128: static int 2129: alter_cond (cond) 2130: register rtx cond; 2131: { 2132: int value = 0; 2133: 2134: if (cc_status.flags & CC_REVERSED) 2135: { 2136: value = 2; 2137: PUT_CODE (cond, swap_condition (GET_CODE (cond))); 2138: } 2139: 2140: if (cc_status.flags & CC_INVERTED) 2141: { 2142: value = 2; 2143: PUT_CODE (cond, reverse_condition (GET_CODE (cond))); 2144: } 2145: 2146: if (cc_status.flags & CC_NOT_POSITIVE) 2147: switch (GET_CODE (cond)) 2148: { 2149: case LE: 2150: case LEU: 2151: case GEU: 2152: /* Jump becomes unconditional. */ 2153: return 1; 2154: 2155: case GT: 2156: case GTU: 2157: case LTU: 2158: /* Jump becomes no-op. */ 2159: return -1; 2160: 2161: case GE: 2162: PUT_CODE (cond, EQ); 2163: value = 2; 2164: break; 2165: 2166: case LT: 2167: PUT_CODE (cond, NE); 2168: value = 2; 2169: break; 2170: } 2171: 2172: if (cc_status.flags & CC_NOT_NEGATIVE) 2173: switch (GET_CODE (cond)) 2174: { 2175: case GE: 2176: case GEU: 2177: /* Jump becomes unconditional. */ 2178: return 1; 2179: 2180: case LT: 2181: case LTU: 2182: /* Jump becomes no-op. */ 2183: return -1; 2184: 2185: case LE: 2186: case LEU: 2187: PUT_CODE (cond, EQ); 2188: value = 2; 2189: break; 2190: 2191: case GT: 2192: case GTU: 2193: PUT_CODE (cond, NE); 2194: value = 2; 2195: break; 2196: } 2197: 2198: if (cc_status.flags & CC_NO_OVERFLOW) 2199: switch (GET_CODE (cond)) 2200: { 2201: case GEU: 2202: /* Jump becomes unconditional. */ 2203: return 1; 2204: 2205: case LEU: 2206: PUT_CODE (cond, EQ); 2207: value = 2; 2208: break; 2209: 2210: case GTU: 2211: PUT_CODE (cond, NE); 2212: value = 2; 2213: break; 2214: 2215: case LTU: 2216: /* Jump becomes no-op. */ 2217: return -1; 2218: } 2219: 2220: if (cc_status.flags & (CC_Z_IN_NOT_N | CC_Z_IN_N)) 2221: switch (GET_CODE (cond)) 2222: { 2223: case LE: 2224: case LEU: 2225: case GE: 2226: case GEU: 2227: case LT: 2228: case LTU: 2229: case GT: 2230: case GTU: 2231: abort (); 2232: 2233: case NE: 2234: PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? GE : LT); 2235: value = 2; 2236: break; 2237: 2238: case EQ: 2239: PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? LT : GE); 2240: value = 2; 2241: break; 2242: } 1.1.1.4 root 2243: 2244: if (cc_status.flags & CC_NOT_SIGNED) 2245: /* The flags are valid if signed condition operators are converted 2246: to unsigned. */ 2247: switch (GET_CODE (cond)) 2248: { 2249: case LE: 2250: PUT_CODE (cond, LEU); 2251: value = 2; 2252: break; 2253: 2254: case LT: 2255: PUT_CODE (cond, LTU); 2256: value = 2; 2257: break; 2258: 2259: case GT: 2260: PUT_CODE (cond, GTU); 2261: value = 2; 2262: break; 2263: 2264: case GE: 2265: PUT_CODE (cond, GEU); 2266: value = 2; 2267: break; 2268: } 2269: 1.1 root 2270: return value; 2271: } 2272: #endif 2273: 2274: /* Report inconsistency between the assembler template and the operands. 2275: In an `asm', it's the user's fault; otherwise, the compiler's fault. */ 2276: 2277: void 2278: output_operand_lossage (str) 2279: char *str; 2280: { 2281: if (this_is_asm_operands) 2282: error_for_asm (this_is_asm_operands, "invalid `asm': %s", str); 2283: else 2284: abort (); 2285: } 2286: 2287: /* Output of assembler code from a template, and its subroutines. */ 2288: 2289: /* Output text from TEMPLATE to the assembler output file, 2290: obeying %-directions to substitute operands taken from 2291: the vector OPERANDS. 2292: 2293: %N (for N a digit) means print operand N in usual manner. 2294: %lN means require operand N to be a CODE_LABEL or LABEL_REF 2295: and print the label name with no punctuation. 2296: %cN means require operand N to be a constant 2297: and print the constant expression with no punctuation. 2298: %aN means expect operand N to be a memory address 2299: (not a memory reference!) and print a reference 2300: to that address. 2301: %nN means expect operand N to be a constant 2302: and print a constant expression for minus the value 2303: of the operand, with no other punctuation. */ 2304: 2305: void 2306: output_asm_insn (template, operands) 2307: char *template; 2308: rtx *operands; 2309: { 2310: register char *p; 1.1.1.6 root 2311: register int c, i; 1.1 root 2312: 2313: /* An insn may return a null string template 2314: in a case where no assembler code is needed. */ 2315: if (*template == 0) 2316: return; 2317: 2318: p = template; 2319: putc ('\t', asm_out_file); 2320: 2321: #ifdef ASM_OUTPUT_OPCODE 2322: ASM_OUTPUT_OPCODE (asm_out_file, p); 2323: #endif 2324: 2325: while (c = *p++) 1.1.1.6 root 2326: switch (c) 2327: { 1.1 root 2328: #ifdef ASM_OUTPUT_OPCODE 1.1.1.6 root 2329: case '\n': 1.1 root 2330: putc (c, asm_out_file); 1.1.1.6 root 2331: while ((c = *p) == '\t') 2332: { 2333: putc (c, asm_out_file); 2334: p++; 2335: } 2336: ASM_OUTPUT_OPCODE (asm_out_file, p); 2337: break; 2338: #endif 2339: 2340: #ifdef ASSEMBLER_DIALECT 2341: case '{': 2342: /* If we want the first dialect, do nothing. Otherwise, skip 2343: DIALECT_NUMBER of strings ending with '|'. */ 2344: for (i = 0; i < dialect_number; i++) 2345: { 2346: while (*p && *p++ != '|') 2347: ; 2348: 2349: if (*p == '|') 1.1.1.4 root 2350: p++; 1.1.1.6 root 2351: } 2352: break; 1.1 root 2353: 1.1.1.6 root 2354: case '|': 2355: /* Skip to close brace. */ 2356: while (*p && *p++ != '}') 2357: ; 2358: break; 2359: 2360: case '}': 2361: break; 2362: #endif 2363: 2364: case '%': 2365: /* %% outputs a single %. */ 2366: if (*p == '%') 2367: { 2368: p++; 2369: putc (c, asm_out_file); 2370: } 2371: /* %= outputs a number which is unique to each insn in the entire 2372: compilation. This is useful for making local labels that are 2373: referred to more than once in a given insn. */ 2374: else if (*p == '=') 2375: { 2376: p++; 2377: fprintf (asm_out_file, "%d", insn_counter); 2378: } 2379: /* % followed by a letter and some digits 2380: outputs an operand in a special way depending on the letter. 2381: Letters `acln' are implemented directly. 2382: Other letters are passed to `output_operand' so that 2383: the PRINT_OPERAND macro can define them. */ 2384: else if ((*p >= 'a' && *p <= 'z') 2385: || (*p >= 'A' && *p <= 'Z')) 2386: { 2387: int letter = *p++; 2388: c = atoi (p); 2389: 2390: if (! (*p >= '0' && *p <= '9')) 2391: output_operand_lossage ("operand number missing after %-letter"); 2392: else if (this_is_asm_operands && c >= (unsigned) insn_noperands) 2393: output_operand_lossage ("operand number out of range"); 2394: else if (letter == 'l') 2395: output_asm_label (operands[c]); 2396: else if (letter == 'a') 2397: output_address (operands[c]); 2398: else if (letter == 'c') 2399: { 2400: if (CONSTANT_ADDRESS_P (operands[c])) 2401: output_addr_const (asm_out_file, operands[c]); 2402: else 2403: output_operand (operands[c], 'c'); 2404: } 2405: else if (letter == 'n') 2406: { 2407: if (GET_CODE (operands[c]) == CONST_INT) 2408: fprintf (asm_out_file, 1.1.1.4 root 2409: #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT 1.1.1.6 root 2410: "%d", 1.1.1.4 root 2411: #else 1.1.1.6 root 2412: "%ld", 1.1.1.4 root 2413: #endif 1.1.1.6 root 2414: - INTVAL (operands[c])); 2415: else 2416: { 2417: putc ('-', asm_out_file); 2418: output_addr_const (asm_out_file, operands[c]); 2419: } 2420: } 2421: else 2422: output_operand (operands[c], letter); 2423: 2424: while ((c = *p) >= '0' && c <= '9') p++; 2425: } 2426: /* % followed by a digit outputs an operand the default way. */ 2427: else if (*p >= '0' && *p <= '9') 2428: { 2429: c = atoi (p); 2430: if (this_is_asm_operands && c >= (unsigned) insn_noperands) 2431: output_operand_lossage ("operand number out of range"); 2432: else 2433: output_operand (operands[c], 0); 2434: while ((c = *p) >= '0' && c <= '9') p++; 2435: } 2436: /* % followed by punctuation: output something for that 2437: punctuation character alone, with no operand. 2438: The PRINT_OPERAND macro decides what is actually done. */ 1.1 root 2439: #ifdef PRINT_OPERAND_PUNCT_VALID_P 1.1.1.6 root 2440: else if (PRINT_OPERAND_PUNCT_VALID_P (*p)) 2441: output_operand (NULL_RTX, *p++); 1.1 root 2442: #endif 1.1.1.6 root 2443: else 2444: output_operand_lossage ("invalid %%-code"); 2445: break; 2446: 2447: default: 2448: putc (c, asm_out_file); 2449: } 1.1 root 2450: 2451: if (flag_print_asm_name) 2452: { 2453: /* Annotate the assembly with a comment describing the pattern and 2454: alternative used. */ 2455: if (debug_insn) 2456: { 2457: register int num = INSN_CODE (debug_insn); 2458: fprintf (asm_out_file, " %s %d %s", 2459: ASM_COMMENT_START, INSN_UID (debug_insn), insn_name[num]); 2460: if (insn_n_alternatives[num] > 1) 2461: fprintf (asm_out_file, "/%d", which_alternative + 1); 2462: 2463: /* Clear this so only the first assembler insn 2464: of any rtl insn will get the special comment for -dp. */ 2465: debug_insn = 0; 2466: } 2467: } 2468: 2469: putc ('\n', asm_out_file); 2470: } 2471: 2472: /* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol. */ 2473: 2474: void 2475: output_asm_label (x) 2476: rtx x; 2477: { 2478: char buf[256]; 2479: 2480: if (GET_CODE (x) == LABEL_REF) 2481: ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0))); 2482: else if (GET_CODE (x) == CODE_LABEL) 2483: ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x)); 2484: else 2485: output_operand_lossage ("`%l' operand isn't a label"); 2486: 2487: assemble_name (asm_out_file, buf); 2488: } 2489: 2490: /* Print operand X using machine-dependent assembler syntax. 2491: The macro PRINT_OPERAND is defined just to control this function. 2492: CODE is a non-digit that preceded the operand-number in the % spec, 2493: such as 'z' if the spec was `%z3'. CODE is 0 if there was no char 2494: between the % and the digits. 2495: When CODE is a non-letter, X is 0. 2496: 2497: The meanings of the letters are machine-dependent and controlled 2498: by PRINT_OPERAND. */ 2499: 2500: static void 2501: output_operand (x, code) 2502: rtx x; 2503: int code; 2504: { 2505: if (x && GET_CODE (x) == SUBREG) 2506: x = alter_subreg (x); 1.1.1.4 root 2507: 2508: /* If X is a pseudo-register, abort now rather than writing trash to the 2509: assembler file. */ 2510: 2511: if (x && GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER) 2512: abort (); 2513: 1.1 root 2514: PRINT_OPERAND (asm_out_file, x, code); 2515: } 2516: 2517: /* Print a memory reference operand for address X 2518: using machine-dependent assembler syntax. 2519: The macro PRINT_OPERAND_ADDRESS exists just to control this function. */ 2520: 2521: void 2522: output_address (x) 2523: rtx x; 2524: { 2525: walk_alter_subreg (x); 2526: PRINT_OPERAND_ADDRESS (asm_out_file, x); 2527: } 2528: 2529: /* Print an integer constant expression in assembler syntax. 2530: Addition and subtraction are the only arithmetic 2531: that may appear in these expressions. */ 2532: 2533: void 2534: output_addr_const (file, x) 2535: FILE *file; 2536: rtx x; 2537: { 2538: char buf[256]; 2539: 2540: restart: 2541: switch (GET_CODE (x)) 2542: { 2543: case PC: 2544: if (flag_pic) 2545: putc ('.', file); 2546: else 2547: abort (); 2548: break; 2549: 2550: case SYMBOL_REF: 2551: assemble_name (file, XSTR (x, 0)); 2552: break; 2553: 2554: case LABEL_REF: 2555: ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0))); 1.1.1.4 root 2556: assemble_name (file, buf); 1.1 root 2557: break; 2558: 2559: case CODE_LABEL: 2560: ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x)); 1.1.1.4 root 2561: assemble_name (file, buf); 1.1 root 2562: break; 2563: 2564: case CONST_INT: 1.1.1.4 root 2565: fprintf (file, 2566: #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT 2567: "%d", 2568: #else 2569: "%ld", 2570: #endif 2571: INTVAL (x)); 1.1 root 2572: break; 2573: 2574: case CONST: 2575: /* This used to output parentheses around the expression, 2576: but that does not work on the 386 (either ATT or BSD assembler). */ 2577: output_addr_const (file, XEXP (x, 0)); 2578: break; 2579: 2580: case CONST_DOUBLE: 2581: if (GET_MODE (x) == VOIDmode) 2582: { 1.1.1.4 root 2583: /* We can use %d if the number is one word and positive. */ 1.1.1.5 root 2584: if (CONST_DOUBLE_HIGH (x)) 1.1.1.4 root 2585: fprintf (file, 2586: #if HOST_BITS_PER_WIDE_INT == 64 2587: #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT 1.1.1.5 root 2588: "0x%lx%016lx", 1.1.1.4 root 2589: #else 1.1.1.5 root 2590: "0x%x%016x", 1.1.1.4 root 2591: #endif 2592: #else 2593: #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT 1.1.1.5 root 2594: "0x%lx%08lx", 1.1.1.4 root 2595: #else 1.1.1.5 root 2596: "0x%x%08x", 1.1.1.4 root 2597: #endif 2598: #endif 1.1 root 2599: CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x)); 1.1.1.5 root 2600: else if (CONST_DOUBLE_LOW (x) < 0) 2601: fprintf (file, 2602: #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT 2603: "0x%x", 2604: #else 2605: "0x%lx", 2606: #endif 2607: CONST_DOUBLE_LOW (x)); 1.1 root 2608: else 1.1.1.4 root 2609: fprintf (file, 2610: #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT 2611: "%d", 2612: #else 2613: "%ld", 2614: #endif 2615: CONST_DOUBLE_LOW (x)); 1.1 root 2616: } 2617: else 2618: /* We can't handle floating point constants; 2619: PRINT_OPERAND must handle them. */ 2620: output_operand_lossage ("floating constant misused"); 2621: break; 2622: 2623: case PLUS: 2624: /* Some assemblers need integer constants to appear last (eg masm). */ 2625: if (GET_CODE (XEXP (x, 0)) == CONST_INT) 2626: { 2627: output_addr_const (file, XEXP (x, 1)); 2628: if (INTVAL (XEXP (x, 0)) >= 0) 2629: fprintf (file, "+"); 2630: output_addr_const (file, XEXP (x, 0)); 2631: } 2632: else 2633: { 2634: output_addr_const (file, XEXP (x, 0)); 2635: if (INTVAL (XEXP (x, 1)) >= 0) 2636: fprintf (file, "+"); 2637: output_addr_const (file, XEXP (x, 1)); 2638: } 2639: break; 2640: 2641: case MINUS: 1.1.1.4 root 2642: /* Avoid outputting things like x-x or x+5-x, 2643: since some assemblers can't handle that. */ 2644: x = simplify_subtraction (x); 2645: if (GET_CODE (x) != MINUS) 2646: goto restart; 2647: 1.1 root 2648: output_addr_const (file, XEXP (x, 0)); 2649: fprintf (file, "-"); 1.1.1.4 root 2650: if (GET_CODE (XEXP (x, 1)) == CONST_INT 2651: && INTVAL (XEXP (x, 1)) < 0) 2652: { 2653: fprintf (file, ASM_OPEN_PAREN); 2654: output_addr_const (file, XEXP (x, 1)); 2655: fprintf (file, ASM_CLOSE_PAREN); 2656: } 2657: else 2658: output_addr_const (file, XEXP (x, 1)); 2659: break; 2660: 2661: case ZERO_EXTEND: 2662: case SIGN_EXTEND: 2663: output_addr_const (file, XEXP (x, 0)); 1.1 root 2664: break; 2665: 2666: default: 2667: output_operand_lossage ("invalid expression as operand"); 2668: } 2669: } 2670: 2671: /* A poor man's fprintf, with the added features of %I, %R, %L, and %U. 2672: %R prints the value of REGISTER_PREFIX. 2673: %L prints the value of LOCAL_LABEL_PREFIX. 2674: %U prints the value of USER_LABEL_PREFIX. 2675: %I prints the value of IMMEDIATE_PREFIX. 1.1.1.2 root 2676: %O runs ASM_OUTPUT_OPCODE to transform what follows in the string. 1.1.1.6 root 2677: Also supported are %d, %x, %s, %e, %f, %g and %%. 2678: 2679: We handle alternate assembler dialects here, just like output_asm_insn. */ 1.1 root 2680: 2681: void 1.1.1.7 ! root 2682: asm_fprintf VPROTO((FILE *file, char *p, ...)) 1.1 root 2683: { 1.1.1.7 ! root 2684: #ifndef __STDC__ 1.1 root 2685: FILE *file; 1.1.1.7 ! root 2686: char *p; ! 2687: #endif ! 2688: va_list argptr; 1.1 root 2689: char buf[10]; 1.1.1.7 ! root 2690: char *q, c; 1.1.1.6 root 2691: int i; 1.1 root 2692: 1.1.1.7 ! root 2693: VA_START (argptr, p); ! 2694: ! 2695: #ifndef __STDC__ ! 2696: file = va_arg (argptr, FILE*); ! 2697: p = va_arg (argptr, char*); ! 2698: #endif 1.1 root 2699: 2700: buf[0] = '%'; 2701: 2702: while (c = *p++) 2703: switch (c) 2704: { 1.1.1.6 root 2705: #ifdef ASSEMBLER_DIALECT 2706: case '{': 2707: /* If we want the first dialect, do nothing. Otherwise, skip 2708: DIALECT_NUMBER of strings ending with '|'. */ 2709: for (i = 0; i < dialect_number; i++) 2710: { 2711: while (*p && *p++ != '|') 2712: ; 2713: 2714: if (*p == '|') 2715: p++; 2716: } 2717: break; 2718: 2719: case '|': 2720: /* Skip to close brace. */ 2721: while (*p && *p++ != '}') 2722: ; 2723: break; 2724: 2725: case '}': 2726: break; 2727: #endif 2728: 1.1 root 2729: case '%': 2730: c = *p++; 2731: q = &buf[1]; 2732: while ((c >= '0' && c <= '9') || c == '.') 2733: { 2734: *q++ = c; 2735: c = *p++; 2736: } 2737: switch (c) 2738: { 2739: case '%': 2740: fprintf (file, "%%"); 2741: break; 2742: 2743: case 'd': case 'i': case 'u': 2744: case 'x': case 'p': case 'X': 2745: case 'o': 2746: *q++ = c; 2747: *q = 0; 2748: fprintf (file, buf, va_arg (argptr, int)); 2749: break; 2750: 1.1.1.6 root 2751: case 'w': 2752: /* This is a prefix to the 'd', 'i', 'u', 'x', 'p', and 'X' cases, 2753: but we do not check for those cases. It means that the value 2754: is a HOST_WIDE_INT, which may be either `int' or `long'. */ 2755: 2756: #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT 2757: *q++ = 'l'; 2758: #endif 2759: 2760: *q++ = *p++; 2761: *q = 0; 2762: fprintf (file, buf, va_arg (argptr, HOST_WIDE_INT)); 2763: break; 2764: 2765: case 'l': 2766: *q++ = c; 2767: *q++ = *p++; 2768: *q = 0; 2769: fprintf (file, buf, va_arg (argptr, long)); 2770: break; 2771: 1.1 root 2772: case 'e': 2773: case 'f': 2774: case 'g': 2775: *q++ = c; 2776: *q = 0; 2777: fprintf (file, buf, va_arg (argptr, double)); 2778: break; 2779: 2780: case 's': 2781: *q++ = c; 2782: *q = 0; 2783: fprintf (file, buf, va_arg (argptr, char *)); 2784: break; 2785: 1.1.1.2 root 2786: case 'O': 2787: #ifdef ASM_OUTPUT_OPCODE 2788: ASM_OUTPUT_OPCODE (asm_out_file, p); 2789: #endif 2790: break; 2791: 1.1 root 2792: case 'R': 2793: #ifdef REGISTER_PREFIX 2794: fprintf (file, "%s", REGISTER_PREFIX); 2795: #endif 2796: break; 2797: 2798: case 'I': 2799: #ifdef IMMEDIATE_PREFIX 2800: fprintf (file, "%s", IMMEDIATE_PREFIX); 2801: #endif 2802: break; 2803: 2804: case 'L': 2805: #ifdef LOCAL_LABEL_PREFIX 2806: fprintf (file, "%s", LOCAL_LABEL_PREFIX); 2807: #endif 2808: break; 2809: 2810: case 'U': 2811: #ifdef USER_LABEL_PREFIX 2812: fprintf (file, "%s", USER_LABEL_PREFIX); 2813: #endif 2814: break; 2815: 2816: default: 2817: abort (); 2818: } 2819: break; 2820: 2821: default: 2822: fputc (c, file); 2823: } 2824: } 2825: 2826: /* Split up a CONST_DOUBLE or integer constant rtx 2827: into two rtx's for single words, 2828: storing in *FIRST the word that comes first in memory in the target 2829: and in *SECOND the other. */ 2830: 2831: void 2832: split_double (value, first, second) 2833: rtx value; 2834: rtx *first, *second; 2835: { 2836: if (GET_CODE (value) == CONST_INT) 2837: { 2838: /* The rule for using CONST_INT for a wider mode 2839: is that we regard the value as signed. 2840: So sign-extend it. */ 2841: rtx high = (INTVAL (value) < 0 ? constm1_rtx : const0_rtx); 2842: #if WORDS_BIG_ENDIAN 2843: *first = high; 2844: *second = value; 2845: #else 2846: *first = value; 2847: *second = high; 2848: #endif 2849: } 2850: else if (GET_CODE (value) != CONST_DOUBLE) 2851: { 2852: #if WORDS_BIG_ENDIAN 2853: *first = const0_rtx; 2854: *second = value; 2855: #else 2856: *first = value; 2857: *second = const0_rtx; 2858: #endif 2859: } 2860: else if (GET_MODE (value) == VOIDmode 2861: /* This is the old way we did CONST_DOUBLE integers. */ 2862: || GET_MODE_CLASS (GET_MODE (value)) == MODE_INT) 2863: { 2864: /* In an integer, the words are defined as most and least significant. 2865: So order them by the target's convention. */ 2866: #if WORDS_BIG_ENDIAN 1.1.1.4 root 2867: *first = GEN_INT (CONST_DOUBLE_HIGH (value)); 2868: *second = GEN_INT (CONST_DOUBLE_LOW (value)); 1.1 root 2869: #else 1.1.1.4 root 2870: *first = GEN_INT (CONST_DOUBLE_LOW (value)); 2871: *second = GEN_INT (CONST_DOUBLE_HIGH (value)); 1.1 root 2872: #endif 2873: } 2874: else 2875: { 1.1.1.5 root 2876: #ifdef REAL_ARITHMETIC 1.1.1.7 ! root 2877: REAL_VALUE_TYPE r; long l[2]; 1.1.1.5 root 2878: REAL_VALUE_FROM_CONST_DOUBLE (r, value); 1.1.1.7 ! root 2879: ! 2880: /* Note, this converts the REAL_VALUE_TYPE to the target's ! 2881: format, splits up the floating point double and outputs ! 2882: exactly 32 bits of it into each of l[0] and l[1] -- ! 2883: not necessarily BITS_PER_WORD bits. */ 1.1.1.5 root 2884: REAL_VALUE_TO_TARGET_DOUBLE (r, l); 1.1.1.7 ! root 2885: ! 2886: *first = GEN_INT ((HOST_WIDE_INT) l[0]); ! 2887: *second = GEN_INT ((HOST_WIDE_INT) l[1]); 1.1.1.5 root 2888: #else 1.1 root 2889: if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT 1.1.1.4 root 2890: || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD) 1.1 root 2891: && ! flag_pretend_float) 2892: abort (); 2893: 2894: #if defined (HOST_WORDS_BIG_ENDIAN) == WORDS_BIG_ENDIAN 2895: /* Host and target agree => no need to swap. */ 1.1.1.4 root 2896: *first = GEN_INT (CONST_DOUBLE_LOW (value)); 2897: *second = GEN_INT (CONST_DOUBLE_HIGH (value)); 1.1 root 2898: #else 1.1.1.4 root 2899: *second = GEN_INT (CONST_DOUBLE_LOW (value)); 2900: *first = GEN_INT (CONST_DOUBLE_HIGH (value)); 1.1 root 2901: #endif 1.1.1.5 root 2902: #endif /* no REAL_ARITHMETIC */ 1.1 root 2903: } 2904: } 2905: 2906: /* Return nonzero if this function has no function calls. */ 2907: 2908: int 2909: leaf_function_p () 2910: { 2911: rtx insn; 2912: 2913: if (profile_flag || profile_block_flag) 2914: return 0; 2915: 2916: for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 2917: { 2918: if (GET_CODE (insn) == CALL_INSN) 2919: return 0; 2920: if (GET_CODE (insn) == INSN 2921: && GET_CODE (PATTERN (insn)) == SEQUENCE 2922: && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN) 2923: return 0; 2924: } 2925: for (insn = current_function_epilogue_delay_list; insn; insn = XEXP (insn, 1)) 2926: { 2927: if (GET_CODE (XEXP (insn, 0)) == CALL_INSN) 2928: return 0; 2929: if (GET_CODE (XEXP (insn, 0)) == INSN 2930: && GET_CODE (PATTERN (XEXP (insn, 0))) == SEQUENCE 2931: && GET_CODE (XVECEXP (PATTERN (XEXP (insn, 0)), 0, 0)) == CALL_INSN) 2932: return 0; 2933: } 2934: 2935: return 1; 2936: } 2937: 2938: /* On some machines, a function with no call insns 2939: can run faster if it doesn't create its own register window. 2940: When output, the leaf function should use only the "output" 2941: registers. Ordinarily, the function would be compiled to use 2942: the "input" registers to find its arguments; it is a candidate 2943: for leaf treatment if it uses only the "input" registers. 2944: Leaf function treatment means renumbering so the function 2945: uses the "output" registers instead. */ 2946: 2947: #ifdef LEAF_REGISTERS 2948: 2949: static char permitted_reg_in_leaf_functions[] = LEAF_REGISTERS; 2950: 2951: /* Return 1 if this function uses only the registers that can be 2952: safely renumbered. */ 2953: 2954: int 2955: only_leaf_regs_used () 2956: { 2957: int i; 2958: 2959: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 2960: { 1.1.1.4 root 2961: if ((regs_ever_live[i] || global_regs[i]) 2962: && ! permitted_reg_in_leaf_functions[i]) 1.1 root 2963: return 0; 2964: } 2965: return 1; 2966: } 2967: 2968: /* Scan all instructions and renumber all registers into those 2969: available in leaf functions. */ 2970: 2971: static void 2972: leaf_renumber_regs (first) 2973: rtx first; 2974: { 2975: rtx insn; 2976: 2977: /* Renumber only the actual patterns. 2978: The reg-notes can contain frame pointer refs, 2979: and renumbering them could crash, and should not be needed. */ 2980: for (insn = first; insn; insn = NEXT_INSN (insn)) 2981: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') 2982: leaf_renumber_regs_insn (PATTERN (insn)); 2983: for (insn = current_function_epilogue_delay_list; insn; insn = XEXP (insn, 1)) 2984: if (GET_RTX_CLASS (GET_CODE (XEXP (insn, 0))) == 'i') 2985: leaf_renumber_regs_insn (PATTERN (XEXP (insn, 0))); 2986: } 2987: 2988: /* Scan IN_RTX and its subexpressions, and renumber all regs into those 2989: available in leaf functions. */ 2990: 2991: void 2992: leaf_renumber_regs_insn (in_rtx) 2993: register rtx in_rtx; 2994: { 2995: register int i, j; 2996: register char *format_ptr; 2997: 2998: if (in_rtx == 0) 2999: return; 3000: 3001: /* Renumber all input-registers into output-registers. 3002: renumbered_regs would be 1 for an output-register; 3003: they */ 3004: 3005: if (GET_CODE (in_rtx) == REG) 3006: { 3007: int newreg; 3008: 3009: /* Don't renumber the same reg twice. */ 3010: if (in_rtx->used) 3011: return; 3012: 3013: newreg = REGNO (in_rtx); 1.1.1.2 root 3014: /* Don't try to renumber pseudo regs. It is possible for a pseudo reg 1.1 root 3015: to reach here as part of a REG_NOTE. */ 3016: if (newreg >= FIRST_PSEUDO_REGISTER) 3017: { 3018: in_rtx->used = 1; 3019: return; 3020: } 3021: newreg = LEAF_REG_REMAP (newreg); 3022: if (newreg < 0) 3023: abort (); 3024: regs_ever_live[REGNO (in_rtx)] = 0; 3025: regs_ever_live[newreg] = 1; 3026: REGNO (in_rtx) = newreg; 3027: in_rtx->used = 1; 3028: } 3029: 3030: if (GET_RTX_CLASS (GET_CODE (in_rtx)) == 'i') 3031: { 3032: /* Inside a SEQUENCE, we find insns. 3033: Renumber just the patterns of these insns, 3034: just as we do for the top-level insns. */ 3035: leaf_renumber_regs_insn (PATTERN (in_rtx)); 3036: return; 3037: } 3038: 3039: format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)); 3040: 3041: for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++) 3042: switch (*format_ptr++) 3043: { 3044: case 'e': 3045: leaf_renumber_regs_insn (XEXP (in_rtx, i)); 3046: break; 3047: 3048: case 'E': 3049: if (NULL != XVEC (in_rtx, i)) 3050: { 3051: for (j = 0; j < XVECLEN (in_rtx, i); j++) 3052: leaf_renumber_regs_insn (XVECEXP (in_rtx, i, j)); 3053: } 3054: break; 3055: 3056: case 'S': 3057: case 's': 3058: case '0': 3059: case 'i': 1.1.1.4 root 3060: case 'w': 1.1 root 3061: case 'n': 3062: case 'u': 3063: break; 3064: 3065: default: 3066: abort (); 3067: } 3068: } 3069: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.