1/* Convert RTL to assembler code and output it, for GNU compiler. 2 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 3 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it under 8the terms of the GNU General Public License as published by the Free --- 54 unchanged lines hidden (view full) --- 63#include "function.h" 64#include "toplev.h" 65#include "reload.h" 66#include "intl.h" 67#include "basic-block.h" 68#include "target.h" 69#include "debug.h" 70#include "expr.h" |
71#include "profile.h" 72#include "cfglayout.h" |
73 74#ifdef XCOFF_DEBUGGING_INFO 75#include "xcoffout.h" /* Needed for external data 76 declarations for e.g. AIX 4.x. */ 77#endif 78 79#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) 80#include "dwarf2out.h" --- 14 unchanged lines hidden (view full) --- 95#ifndef IS_ASM_LOGICAL_LINE_SEPARATOR 96#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == ';') 97#endif 98 99#ifndef JUMP_TABLES_IN_TEXT_SECTION 100#define JUMP_TABLES_IN_TEXT_SECTION 0 101#endif 102 |
103#if defined(READONLY_DATA_SECTION) || defined(READONLY_DATA_SECTION_ASM_OP) 104#define HAVE_READONLY_DATA_SECTION 1 105#else 106#define HAVE_READONLY_DATA_SECTION 0 107#endif 108 |
109/* Last insn processed by final_scan_insn. */ 110static rtx debug_insn; 111rtx current_output_insn; 112 113/* Line number of last NOTE. */ 114static int last_linenum; 115 116/* Highest line number in current block. */ 117static int high_block_linenum; 118 119/* Likewise for function. */ 120static int high_function_linenum; 121 122/* Filename of last NOTE. */ 123static const char *last_filename; 124 |
125extern int length_unit_log; /* This is defined in insn-attrtab.c. */ 126 127/* Nonzero while outputting an `asm' with operands. 128 This means that inconsistencies are the user's fault, so don't abort. 129 The precise value is the insn being output, to pass to error_for_asm. */ |
130rtx this_is_asm_operands; |
131 132/* Number of operands of this insn, for an `asm' with operands. */ 133static unsigned int insn_noperands; 134 135/* Compare optimization flag. */ 136 137static rtx last_ignored_compare = 0; 138 --- 59 unchanged lines hidden (view full) --- 198 199static char *line_note_exists; 200 201#ifdef HAVE_conditional_execution 202/* Nonnull if the insn currently being emitted was a COND_EXEC pattern. */ 203rtx current_insn_predicate; 204#endif 205 |
206struct function_list 207{ 208 struct function_list *next; /* next function */ 209 const char *name; /* function name */ 210 long cfg_checksum; /* function checksum */ 211 long count_edges; /* number of intrumented edges in this function */ 212}; 213 214static struct function_list *functions_head = 0; 215static struct function_list **functions_tail = &functions_head; 216 |
217#ifdef HAVE_ATTR_length 218static int asm_insn_count PARAMS ((rtx)); 219#endif 220static void profile_function PARAMS ((FILE *)); 221static void profile_after_prologue PARAMS ((FILE *)); 222static void notice_source_line PARAMS ((rtx)); 223static rtx walk_alter_subreg PARAMS ((rtx *)); 224static void output_asm_name PARAMS ((void)); |
225static void output_alternate_entry_point PARAMS ((FILE *, rtx)); |
226static tree get_mem_expr_from_op PARAMS ((rtx, int *)); 227static void output_asm_operand_names PARAMS ((rtx *, int *, int)); 228static void output_operand PARAMS ((rtx, int)); 229#ifdef LEAF_REGISTERS 230static void leaf_renumber_regs PARAMS ((rtx)); 231#endif 232#ifdef HAVE_cc0 233static int alter_cond PARAMS ((rtx)); --- 15 unchanged lines hidden (view full) --- 249 final_sequence = 0; 250 251#ifdef ASSEMBLER_DIALECT 252 dialect_number = ASSEMBLER_DIALECT; 253#endif 254} 255 256/* Called at end of source file, |
257 to output the arc-profiling table for this entire compilation. */ |
258 259void 260end_final (filename) 261 const char *filename; 262{ |
263 if (profile_arc_flag && profile_info.count_instrumented_edges) |
264 { 265 char name[20]; |
266 tree string_type, string_cst; 267 tree structure_decl, structure_value, structure_pointer_type; 268 tree field_decl, decl_chain, value_chain; 269 tree sizeof_field_value, domain_type; |
270 |
271 /* Build types. */ 272 string_type = build_pointer_type (char_type_node); |
273 |
274 /* Libgcc2 bb structure. */ 275 structure_decl = make_node (RECORD_TYPE); 276 structure_pointer_type = build_pointer_type (structure_decl); |
277 |
278 /* Output the main header, of 7 words: 279 0: 1 if this file is initialized, else 0. 280 1: address of file name (LPBX1). 281 2: address of table of counts (LPBX2). 282 3: number of counts in the table. 283 4: always 0, libgcc2 uses this as a pointer to next ``struct bb'' |
284 |
285 The following are GNU extensions: |
286 |
287 5: Number of bytes in this header. 288 6: address of table of function checksums (LPBX7). */ |
289 |
290 /* The zero word. */ 291 decl_chain = 292 build_decl (FIELD_DECL, get_identifier ("zero_word"), 293 long_integer_type_node); 294 value_chain = build_tree_list (decl_chain, 295 convert (long_integer_type_node, 296 integer_zero_node)); |
297 |
298 /* Address of filename. */ 299 { 300 char *cwd, *da_filename; 301 int da_filename_len; |
302 |
303 field_decl = 304 build_decl (FIELD_DECL, get_identifier ("filename"), string_type); 305 TREE_CHAIN (field_decl) = decl_chain; 306 decl_chain = field_decl; |
307 |
308 cwd = getpwd (); 309 da_filename_len = strlen (filename) + strlen (cwd) + 4 + 1; 310 da_filename = (char *) alloca (da_filename_len); 311 strcpy (da_filename, cwd); 312 strcat (da_filename, "/"); 313 strcat (da_filename, filename); 314 strcat (da_filename, ".da"); 315 da_filename_len = strlen (da_filename); 316 string_cst = build_string (da_filename_len + 1, da_filename); 317 domain_type = build_index_type (build_int_2 (da_filename_len, 0)); 318 TREE_TYPE (string_cst) 319 = build_array_type (char_type_node, domain_type); 320 value_chain = tree_cons (field_decl, 321 build1 (ADDR_EXPR, string_type, string_cst), 322 value_chain); 323 } |
324 |
325 /* Table of counts. */ 326 { 327 tree gcov_type_type = make_unsigned_type (GCOV_TYPE_SIZE); 328 tree gcov_type_pointer_type = build_pointer_type (gcov_type_type); 329 tree domain_tree 330 = build_index_type (build_int_2 (profile_info. 331 count_instrumented_edges - 1, 0)); 332 tree gcov_type_array_type 333 = build_array_type (gcov_type_type, domain_tree); 334 tree gcov_type_array_pointer_type 335 = build_pointer_type (gcov_type_array_type); 336 tree counts_table; |
337 |
338 field_decl = 339 build_decl (FIELD_DECL, get_identifier ("counts"), 340 gcov_type_pointer_type); 341 TREE_CHAIN (field_decl) = decl_chain; 342 decl_chain = field_decl; |
343 |
344 /* No values. */ 345 counts_table 346 = build (VAR_DECL, gcov_type_array_type, NULL_TREE, NULL_TREE); 347 TREE_STATIC (counts_table) = 1; 348 ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 2); 349 DECL_NAME (counts_table) = get_identifier (name); 350 assemble_variable (counts_table, 0, 0, 0); |
351 |
352 value_chain = tree_cons (field_decl, 353 build1 (ADDR_EXPR, 354 gcov_type_array_pointer_type, 355 counts_table), value_chain); 356 } 357 |
358 /* Count of the # of instrumented arcs. */ |
359 field_decl 360 = build_decl (FIELD_DECL, get_identifier ("ncounts"), 361 long_integer_type_node); 362 TREE_CHAIN (field_decl) = decl_chain; 363 decl_chain = field_decl; |
364 |
365 value_chain = tree_cons (field_decl, 366 convert (long_integer_type_node, 367 build_int_2 (profile_info. 368 count_instrumented_edges, 369 0)), value_chain); 370 /* Pointer to the next bb. */ 371 field_decl 372 = build_decl (FIELD_DECL, get_identifier ("next"), 373 structure_pointer_type); 374 TREE_CHAIN (field_decl) = decl_chain; 375 decl_chain = field_decl; |
376 |
377 value_chain = tree_cons (field_decl, null_pointer_node, value_chain); |
378 |
379 /* sizeof(struct bb). We'll set this after entire structure 380 is laid out. */ 381 field_decl 382 = build_decl (FIELD_DECL, get_identifier ("sizeof_bb"), 383 long_integer_type_node); 384 TREE_CHAIN (field_decl) = decl_chain; 385 decl_chain = field_decl; |
386 |
387 sizeof_field_value = tree_cons (field_decl, NULL, value_chain); 388 value_chain = sizeof_field_value; |
389 |
390 /* struct bb_function []. */ 391 { 392 struct function_list *item; 393 int num_nodes; 394 tree checksum_field, arc_count_field, name_field; 395 tree domain; 396 tree array_value_chain = NULL_TREE; 397 tree bb_fn_struct_type; 398 tree bb_fn_struct_array_type; 399 tree bb_fn_struct_array_pointer_type; 400 tree bb_fn_struct_pointer_type; 401 tree field_value, field_value_chain; |
402 |
403 bb_fn_struct_type = make_node (RECORD_TYPE); |
404 |
405 checksum_field = build_decl (FIELD_DECL, get_identifier ("checksum"), 406 long_integer_type_node); |
407 |
408 arc_count_field 409 = build_decl (FIELD_DECL, get_identifier ("arc_count"), 410 integer_type_node); 411 TREE_CHAIN (checksum_field) = arc_count_field; 412 413 name_field 414 = build_decl (FIELD_DECL, get_identifier ("name"), string_type); 415 TREE_CHAIN (arc_count_field) = name_field; 416 417 TYPE_FIELDS (bb_fn_struct_type) = checksum_field; 418 419 num_nodes = 0; 420 421 for (item = functions_head; item != 0; item = item->next) 422 num_nodes++; 423 424 /* Note that the array contains a terminator, hence no - 1. */ 425 domain = build_index_type (build_int_2 (num_nodes, 0)); 426 427 bb_fn_struct_pointer_type = build_pointer_type (bb_fn_struct_type); 428 bb_fn_struct_array_type 429 = build_array_type (bb_fn_struct_type, domain); 430 bb_fn_struct_array_pointer_type 431 = build_pointer_type (bb_fn_struct_array_type); 432 433 layout_type (bb_fn_struct_type); 434 layout_type (bb_fn_struct_pointer_type); 435 layout_type (bb_fn_struct_array_type); 436 layout_type (bb_fn_struct_array_pointer_type); 437 438 for (item = functions_head; item != 0; item = item->next) 439 { 440 size_t name_len; 441 442 /* create constructor for structure. */ 443 field_value_chain 444 = build_tree_list (checksum_field, 445 convert (long_integer_type_node, 446 build_int_2 (item->cfg_checksum, 0))); 447 field_value_chain 448 = tree_cons (arc_count_field, 449 convert (integer_type_node, 450 build_int_2 (item->count_edges, 0)), 451 field_value_chain); 452 453 name_len = strlen (item->name); 454 string_cst = build_string (name_len + 1, item->name); 455 domain_type = build_index_type (build_int_2 (name_len, 0)); 456 TREE_TYPE (string_cst) 457 = build_array_type (char_type_node, domain_type); 458 field_value_chain = tree_cons (name_field, 459 build1 (ADDR_EXPR, string_type, 460 string_cst), 461 field_value_chain); 462 463 /* Add to chain. */ 464 array_value_chain 465 = tree_cons (NULL_TREE, build (CONSTRUCTOR, 466 bb_fn_struct_type, NULL_TREE, 467 nreverse (field_value_chain)), 468 array_value_chain); 469 } 470 471 /* Add terminator. */ 472 field_value = build_tree_list (arc_count_field, 473 convert (integer_type_node, 474 build_int_2 (-1, 0))); 475 476 array_value_chain = tree_cons (NULL_TREE, 477 build (CONSTRUCTOR, bb_fn_struct_type, 478 NULL_TREE, field_value), 479 array_value_chain); 480 481 482 /* Create constructor for array. */ 483 field_decl 484 = build_decl (FIELD_DECL, get_identifier ("function_infos"), 485 bb_fn_struct_pointer_type); 486 value_chain = tree_cons (field_decl, 487 build1 (ADDR_EXPR, 488 bb_fn_struct_array_pointer_type, 489 build (CONSTRUCTOR, 490 bb_fn_struct_array_type, 491 NULL_TREE, 492 nreverse 493 (array_value_chain))), 494 value_chain); 495 TREE_CHAIN (field_decl) = decl_chain; 496 decl_chain = field_decl; |
497 } 498 |
499 /* Finish structure. */ 500 TYPE_FIELDS (structure_decl) = nreverse (decl_chain); 501 layout_type (structure_decl); 502 503 structure_value 504 = build (VAR_DECL, structure_decl, NULL_TREE, NULL_TREE); 505 DECL_INITIAL (structure_value) 506 = build (CONSTRUCTOR, structure_decl, NULL_TREE, 507 nreverse (value_chain)); 508 TREE_STATIC (structure_value) = 1; 509 ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0); 510 DECL_NAME (structure_value) = get_identifier (name); 511 512 /* Size of this structure. */ 513 TREE_VALUE (sizeof_field_value) 514 = convert (long_integer_type_node, 515 build_int_2 (int_size_in_bytes (structure_decl), 0)); 516 517 /* Build structure. */ 518 assemble_variable (structure_value, 0, 0, 0); |
519 } 520} 521 522/* Default target function prologue and epilogue assembler output. 523 524 If not overridden for epilogue code, then the function body itself 525 contains return instructions wherever needed. */ 526void --- 54 unchanged lines hidden (view full) --- 581/* The next two pages contain routines used to compute the length of an insn 582 and to shorten branches. */ 583 584/* Arrays for insn lengths, and addresses. The latter is referenced by 585 `insn_current_length'. */ 586 587static int *insn_lengths; 588 |
589varray_type insn_addresses_; |
590 591/* Max uid for which the above arrays are valid. */ 592static int insn_lengths_max_uid; 593 594/* Address of insn being processed. Used by `insn_current_length'. */ 595int insn_current_address; 596 597/* Address of insn being processed in previous iteration. */ --- 70 unchanged lines hidden (view full) --- 668 return 0; 669 670 case CALL_INSN: 671 length = insn_default_length (insn); 672 break; 673 674 case JUMP_INSN: 675 body = PATTERN (insn); |
676 if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC) |
677 { 678 /* Alignment is machine-dependent and should be handled by 679 ADDR_VEC_ALIGN. */ 680 } 681 else 682 length = insn_default_length (insn); 683 break; 684 --- 243 unchanged lines hidden (view full) --- 928 + align_fuzz (dest, seq, length_unit_log, ~0)); 929 } 930} 931#endif /* HAVE_ATTR_length */ 932 933void 934compute_alignments () 935{ |
936 int log, max_skip, max_log; |
937 basic_block bb; |
938 939 if (label_align) 940 { 941 free (label_align); 942 label_align = 0; 943 } 944 945 max_labelno = max_label_num (); 946 min_labelno = get_first_label_num (); 947 label_align = (struct label_alignment *) 948 xcalloc (max_labelno - min_labelno + 1, sizeof (struct label_alignment)); 949 950 /* If not optimizing or optimizing for size, don't assign any alignments. */ 951 if (! optimize || optimize_size) 952 return; 953 |
954 FOR_EACH_BB (bb) |
955 { |
956 rtx label = bb->head; 957 int fallthru_frequency = 0, branch_frequency = 0, has_fallthru = 0; 958 edge e; 959 960 if (GET_CODE (label) != CODE_LABEL) 961 continue; 962 max_log = LABEL_ALIGN (label); 963 max_skip = LABEL_ALIGN_MAX_SKIP; --- 13 unchanged lines hidden (view full) --- 977 978 We to catch first case, we align frequently executed blocks. 979 To catch the second, we align blocks that are executed more frequently 980 than the predecessor and the predecessor is likely to not be executed 981 when function is called. */ 982 983 if (!has_fallthru 984 && (branch_frequency > BB_FREQ_MAX / 10 |
985 || (bb->frequency > bb->prev_bb->frequency * 10 986 && (bb->prev_bb->frequency |
987 <= ENTRY_BLOCK_PTR->frequency / 2)))) 988 { 989 log = JUMP_ALIGN (label); 990 if (max_log < log) 991 { 992 max_log = log; 993 max_skip = JUMP_ALIGN_MAX_SKIP; 994 } 995 } 996 /* In case block is frequent and reached mostly by non-fallthru edge, |
997 align it. It is most likely a first block of loop. */ |
998 if (has_fallthru 999 && branch_frequency + fallthru_frequency > BB_FREQ_MAX / 10 |
1000 && branch_frequency > fallthru_frequency * 2) |
1001 { 1002 log = LOOP_ALIGN (label); 1003 if (max_log < log) 1004 { 1005 max_log = log; 1006 max_skip = LOOP_ALIGN_MAX_SKIP; 1007 } 1008 } --- 105 unchanged lines hidden (view full) --- 1114 if (max_log < log) 1115 { 1116 max_log = log; 1117 max_skip = LABEL_ALIGN_MAX_SKIP; 1118 } 1119 next = NEXT_INSN (insn); 1120 /* ADDR_VECs only take room if read-only data goes into the text 1121 section. */ |
1122 if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION) |
1123 if (next && GET_CODE (next) == JUMP_INSN) 1124 { 1125 rtx nextbody = PATTERN (next); 1126 if (GET_CODE (nextbody) == ADDR_VEC 1127 || GET_CODE (nextbody) == ADDR_DIFF_VEC) 1128 { 1129 log = ADDR_VEC_ALIGN (next); 1130 if (max_log < log) --- 133 unchanged lines hidden (view full) --- 1264 if (log) 1265 { 1266 int align = 1 << log; 1267 int new_address = (insn_current_address + align - 1) & -align; 1268 insn_lengths[uid] = new_address - insn_current_address; 1269 } 1270 } 1271 |
1272 INSN_ADDRESSES (uid) = insn_current_address + insn_lengths[uid]; |
1273 1274 if (GET_CODE (insn) == NOTE || GET_CODE (insn) == BARRIER 1275 || GET_CODE (insn) == CODE_LABEL) 1276 continue; 1277 if (INSN_DELETED_P (insn)) 1278 continue; 1279 1280 body = PATTERN (insn); 1281 if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC) 1282 { 1283 /* This only takes room if read-only data goes into the text 1284 section. */ |
1285 if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION) |
1286 insn_lengths[uid] = (XVECLEN (body, 1287 GET_CODE (body) == ADDR_DIFF_VEC) 1288 * GET_MODE_SIZE (GET_MODE (body))); 1289 /* Alignment is handled by ADDR_VEC_ALIGN. */ 1290 } 1291 else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0) 1292 insn_lengths[uid] = asm_insn_count (body) * insn_default_length (insn); 1293 else if (GET_CODE (body) == SEQUENCE) --- 184 unchanged lines hidden (view full) --- 1478 max_addr += align_fuzz (insn, rel_lab, 0, 0); 1479 } 1480 else 1481 max_addr += align_fuzz (max_lab, rel_lab, 0, 0); 1482 } 1483 PUT_MODE (body, CASE_VECTOR_SHORTEN_MODE (min_addr - rel_addr, 1484 max_addr - rel_addr, 1485 body)); |
1486 if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION) |
1487 { 1488 insn_lengths[uid] 1489 = (XVECLEN (body, 1) * GET_MODE_SIZE (GET_MODE (body))); 1490 insn_current_address += insn_lengths[uid]; 1491 if (insn_lengths[uid] != old_length) 1492 something_changed = 1; 1493 } 1494 --- 13 unchanged lines hidden (view full) --- 1508 { 1509 rtx inner_insn = XVECEXP (body, 0, i); 1510 int inner_uid = INSN_UID (inner_insn); 1511 1512 INSN_ADDRESSES (inner_uid) = insn_current_address; 1513 1514 insn_current_address += insn_lengths[inner_uid]; 1515 } |
1516 } |
1517 else 1518 insn_current_address += insn_lengths[uid]; 1519 1520 continue; 1521 } 1522 1523 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE) 1524 { --- 140 unchanged lines hidden (view full) --- 1665 dwarf2out_frame_debug (NULL_RTX); 1666#endif 1667 1668 /* If debugging, assign block numbers to all of the blocks in this 1669 function. */ 1670 if (write_symbols) 1671 { 1672 remove_unnecessary_notes (); |
1673 scope_to_insns_finalize (); |
1674 number_blocks (current_function_decl); 1675 /* We never actually put out begin/end notes for the top-level 1676 block in the function. But, conceptually, that block is 1677 always needed. */ 1678 TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1; 1679 } 1680 1681 /* First output the function prologue: code to set up the stack frame. */ 1682 (*targetm.asm_out.function_prologue) (file, get_frame_size ()); 1683 |
1684 /* If the machine represents the prologue as RTL, the profiling code must 1685 be emitted when NOTE_INSN_PROLOGUE_END is scanned. */ 1686#ifdef HAVE_prologue 1687 if (! HAVE_prologue) 1688#endif 1689 profile_after_prologue (file); 1690} 1691 --- 21 unchanged lines hidden (view full) --- 1713#if defined(STATIC_CHAIN_INCOMING_REGNUM) || defined(STATIC_CHAIN_REGNUM) 1714 int cxt = current_function_needs_context; 1715#endif 1716#endif /* ASM_OUTPUT_REG_PUSH */ 1717 1718#ifndef NO_PROFILE_COUNTERS 1719 data_section (); 1720 ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT)); |
1721 ASM_OUTPUT_INTERNAL_LABEL (file, "LP", current_function_funcdef_no); |
1722 assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1); 1723#endif 1724 1725 function_section (current_function_decl); 1726 1727#if defined(STRUCT_VALUE_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH) 1728 if (sval) 1729 ASM_OUTPUT_REG_PUSH (file, STRUCT_VALUE_INCOMING_REGNUM); --- 13 unchanged lines hidden (view full) --- 1743#if defined(STATIC_CHAIN_REGNUM) && defined(ASM_OUTPUT_REG_PUSH) 1744 if (cxt) 1745 { 1746 ASM_OUTPUT_REG_PUSH (file, STATIC_CHAIN_REGNUM); 1747 } 1748#endif 1749#endif 1750 |
1751 FUNCTION_PROFILER (file, current_function_funcdef_no); |
1752 1753#if defined(STATIC_CHAIN_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH) 1754 if (cxt) 1755 ASM_OUTPUT_REG_POP (file, STATIC_CHAIN_INCOMING_REGNUM); 1756#else 1757#if defined(STATIC_CHAIN_REGNUM) && defined(ASM_OUTPUT_REG_PUSH) 1758 if (cxt) 1759 { --- 26 unchanged lines hidden (view full) --- 1786 1787 (*debug_hooks->end_function) (high_function_linenum); 1788 1789 /* Finally, output the function epilogue: 1790 code to restore the stack frame and return to the caller. */ 1791 (*targetm.asm_out.function_epilogue) (asm_out_file, get_frame_size ()); 1792 1793 /* And debug output. */ |
1794 (*debug_hooks->end_epilogue) (last_linenum, last_filename); |
1795 1796#if defined (DWARF2_UNWIND_INFO) 1797 if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG 1798 && dwarf2out_do_frame ()) |
1799 dwarf2out_end_epilogue (last_linenum, last_filename); |
1800#endif 1801} 1802 1803/* Output assembler code for some insns: all or part of a function. 1804 For description of args, see `final_start_function', above. 1805 1806 PRESCAN is 1 if we are not really outputting, 1807 just scanning as if we were outputting. --- 77 unchanged lines hidden (view full) --- 1885 CC_STATUS_INIT; 1886 1887 /* Output the insns. */ 1888 for (insn = NEXT_INSN (first); insn;) 1889 { 1890#ifdef HAVE_ATTR_length 1891 if ((unsigned) INSN_UID (insn) >= INSN_ADDRESSES_SIZE ()) 1892 { |
1893 /* This can be triggered by bugs elsewhere in the compiler if 1894 new insns are created after init_insn_lengths is called. */ |
1895 if (GET_CODE (insn) == NOTE) 1896 insn_current_address = -1; 1897 else 1898 abort (); |
1899 } 1900 else 1901 insn_current_address = INSN_ADDRESSES (INSN_UID (insn)); 1902#endif /* HAVE_ATTR_length */ 1903 1904 insn = final_scan_insn (insn, file, optimize, prescan, 0); 1905 } 1906 |
1907 /* Store function names for edge-profiling. */ 1908 /* ??? Probably should re-use the existing struct function. */ 1909 1910 if (cfun->arc_profile) 1911 { 1912 struct function_list *new_item = xmalloc (sizeof (struct function_list)); 1913 1914 *functions_tail = new_item; 1915 functions_tail = &new_item->next; 1916 1917 new_item->next = 0; 1918 new_item->name = xstrdup (IDENTIFIER_POINTER 1919 (DECL_ASSEMBLER_NAME (current_function_decl))); 1920 new_item->cfg_checksum = profile_info.current_function_cfg_checksum; 1921 new_item->count_edges = profile_info.count_edges_instrumented_now; 1922 } 1923 |
1924 free (line_note_exists); 1925 line_note_exists = NULL; 1926} 1927 1928const char * 1929get_insn_template (code, insn) 1930 int code; 1931 rtx insn; --- 10 unchanged lines hidden (view full) --- 1942 abort (); 1943 return (*(insn_output_fn) output) (recog_data.operand, insn); 1944 1945 default: 1946 abort (); 1947 } 1948} 1949 |
1950/* Emit the appropriate declaration for an alternate-entry-point 1951 symbol represented by INSN, to FILE. INSN is a CODE_LABEL with 1952 LABEL_KIND != LABEL_NORMAL. 1953 1954 The case fall-through in this function is intentional. */ 1955static void 1956output_alternate_entry_point (file, insn) 1957 FILE *file; 1958 rtx insn; 1959{ 1960 const char *name = LABEL_NAME (insn); 1961 1962 switch (LABEL_KIND (insn)) 1963 { 1964 case LABEL_WEAK_ENTRY: 1965#ifdef ASM_WEAKEN_LABEL 1966 ASM_WEAKEN_LABEL (file, name); 1967#endif 1968 case LABEL_GLOBAL_ENTRY: 1969 (*targetm.asm_out.globalize_label) (file, name); 1970 case LABEL_STATIC_ENTRY: 1971#ifdef ASM_OUTPUT_TYPE_DIRECTIVE 1972 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function"); 1973#endif 1974 ASM_OUTPUT_LABEL (file, name); 1975 break; 1976 1977 case LABEL_NORMAL: 1978 default: 1979 abort (); 1980 } 1981} 1982 |
1983/* The final scan for one insn, INSN. 1984 Args are same as in `final', except that INSN 1985 is the insn being scanned. 1986 Value returned is the next insn to be scanned. 1987 1988 NOPEEPHOLES is the flag to disallow peephole processing (currently 1989 used for within delayed branch sequence output). */ 1990 --- 27 unchanged lines hidden (view full) --- 2018 case NOTE_INSN_DELETED: 2019 case NOTE_INSN_LOOP_BEG: 2020 case NOTE_INSN_LOOP_END: 2021 case NOTE_INSN_LOOP_END_TOP_COND: 2022 case NOTE_INSN_LOOP_CONT: 2023 case NOTE_INSN_LOOP_VTOP: 2024 case NOTE_INSN_FUNCTION_END: 2025 case NOTE_INSN_REPEATED_LINE_NUMBER: |
2026 case NOTE_INSN_EXPECTED_VALUE: 2027 break; 2028 2029 case NOTE_INSN_BASIC_BLOCK: 2030#ifdef IA64_UNWIND_INFO 2031 IA64_UNWIND_EMIT (asm_out_file, insn); 2032#endif 2033 if (flag_debug_asm) --- 17 unchanged lines hidden (view full) --- 2051 break; 2052 2053 case NOTE_INSN_EPILOGUE_BEG: 2054 (*targetm.asm_out.function_begin_epilogue) (file); 2055 break; 2056 2057 case NOTE_INSN_FUNCTION_BEG: 2058 app_disable (); |
2059 (*debug_hooks->end_prologue) (last_linenum, last_filename); |
2060 break; 2061 2062 case NOTE_INSN_BLOCK_BEG: 2063 if (debug_info_level == DINFO_LEVEL_NORMAL 2064 || debug_info_level == DINFO_LEVEL_VERBOSE 2065 || write_symbols == DWARF_DEBUG 2066 || write_symbols == DWARF2_DEBUG 2067 || write_symbols == VMS_AND_DWARF2_DEBUG --- 113 unchanged lines hidden (view full) --- 2181 int max_skip = LABEL_TO_MAX_SKIP (insn); 2182#endif 2183 2184 if (align && NEXT_INSN (insn)) 2185 { 2186#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN 2187 ASM_OUTPUT_MAX_SKIP_ALIGN (file, align, max_skip); 2188#else |
2189#ifdef ASM_OUTPUT_ALIGN_WITH_NOP 2190 ASM_OUTPUT_ALIGN_WITH_NOP (file, align); 2191#else |
2192 ASM_OUTPUT_ALIGN (file, align); 2193#endif |
2194#endif |
2195 } 2196 } 2197#ifdef HAVE_cc0 2198 CC_STATUS_INIT; 2199 /* If this label is reached from only one place, set the condition 2200 codes from the instruction just before the branch. */ 2201 2202 /* Disabled because some insns set cc_status in the C output code --- 66 unchanged lines hidden (view full) --- 2269 } 2270 else 2271 function_section (current_function_decl); 2272 2273#ifdef ASM_OUTPUT_CASE_LABEL 2274 ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn), 2275 NEXT_INSN (insn)); 2276#else |
2277 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn)); |
2278#endif 2279#endif 2280 break; 2281 } 2282 } |
2283 if (LABEL_ALT_ENTRY_P (insn)) 2284 output_alternate_entry_point (file, insn); |
2285 else 2286 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn)); 2287 break; 2288 2289 default: 2290 { 2291 rtx body = PATTERN (insn); 2292 int insn_code_number; --- 412 unchanged lines hidden (view full) --- 2705 /* Try to recognize the instruction. 2706 If successful, verify that the operands satisfy the 2707 constraints for the instruction. Crash if they don't, 2708 since `reload' should have changed them so that they do. */ 2709 2710 insn_code_number = recog_memoized (insn); 2711 cleanup_subreg_operands (insn); 2712 |
2713 /* Dump the insn in the assembly for debugging. */ 2714 if (flag_dump_rtl_in_asm) 2715 { 2716 print_rtx_head = ASM_COMMENT_START; 2717 print_rtl_single (asm_out_file, insn); 2718 print_rtx_head = ""; 2719 } |
2720 2721 if (! constrain_operands_cached (1)) 2722 fatal_insn_not_found (insn); 2723 2724 /* Some target machines need to prescan each insn before 2725 it is output. */ 2726 2727#ifdef FINAL_PRESCAN_INSN --- 193 unchanged lines hidden (view full) --- 2921 else if (GET_CODE (y) == REG) 2922 { 2923 unsigned int regno = subreg_hard_regno (x, 1); 2924 PUT_CODE (x, REG); 2925 REGNO (x) = regno; 2926 ORIGINAL_REGNO (x) = ORIGINAL_REGNO (y); 2927 /* This field has a different meaning for REGs and SUBREGs. Make 2928 sure to clear it! */ |
2929 RTX_FLAG (x, used) = 0; |
2930 } 2931 else 2932 abort (); 2933 } 2934 2935 return *xp; 2936} 2937 --- 198 unchanged lines hidden (view full) --- 3136 char *new_message; 3137 const char *pfx_str; 3138 VA_OPEN (ap, msgid); 3139 VA_FIXEDARG (ap, const char *, msgid); 3140 3141 pfx_str = this_is_asm_operands ? _("invalid `asm': ") : "output_operand: "; 3142 asprintf (&fmt_string, "%s%s", pfx_str, _(msgid)); 3143 vasprintf (&new_message, fmt_string, ap); |
3144 |
3145 if (this_is_asm_operands) 3146 error_for_asm (this_is_asm_operands, "%s", new_message); 3147 else 3148 internal_error ("%s", new_message); 3149 3150 free (fmt_string); 3151 free (new_message); 3152 VA_CLOSE (ap); --- 781 unchanged lines hidden (view full) --- 3934 else 3935 { 3936 *first = GEN_INT (CONST_DOUBLE_LOW (value)); 3937 *second = GEN_INT (CONST_DOUBLE_HIGH (value)); 3938 } 3939 } 3940 else 3941 { |
3942 REAL_VALUE_TYPE r; 3943 long l[2]; 3944 REAL_VALUE_FROM_CONST_DOUBLE (r, value); 3945 3946 /* Note, this converts the REAL_VALUE_TYPE to the target's 3947 format, splits up the floating point double and outputs 3948 exactly 32 bits of it into each of l[0] and l[1] -- 3949 not necessarily BITS_PER_WORD bits. */ --- 12 unchanged lines hidden (view full) --- 3962 l[0] |= ((long) (-1) << 32); 3963 if (l[1] & ((long) 1 << 31)) 3964 l[1] |= ((long) (-1) << 32); 3965 } 3966#endif 3967 3968 *first = GEN_INT ((HOST_WIDE_INT) l[0]); 3969 *second = GEN_INT ((HOST_WIDE_INT) l[1]); |
3970 } 3971} 3972 3973/* Return nonzero if this function has no function calls. */ 3974 3975int 3976leaf_function_p () 3977{ --- 28 unchanged lines hidden (view full) --- 4006 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN 4007 && ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0))) 4008 return 0; 4009 } 4010 4011 return 1; 4012} 4013 |
4014/* Return 1 if branch is a forward branch. |
4015 Uses insn_shuid array, so it works only in the final pass. May be used by 4016 output templates to customary add branch prediction hints. 4017 */ 4018int 4019final_forward_branch_p (insn) 4020 rtx insn; 4021{ 4022 int insn_id, label_id; --- 148 unchanged lines hidden --- |