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