/* Convert RTL to assembler code and output it, for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GCC.
/* Line number of last NOTE. */
static int last_linenum;
+/* Last discriminator written to assembly. */
+static int last_discriminator;
+
+/* Discriminator of current block. */
+static int discriminator;
+
/* Highest line number in current block. */
static int high_block_linenum;
int
label_to_alignment (rtx label)
{
- return LABEL_TO_ALIGNMENT (label);
+ if (CODE_LABEL_NUMBER (label) <= max_labelno)
+ return LABEL_TO_ALIGNMENT (label);
+ return 0;
+}
+
+int
+label_to_max_skip (rtx label)
+{
+ if (CODE_LABEL_NUMBER (label) <= max_labelno)
+ return LABEL_TO_MAX_SKIP (label);
+ return 0;
}
#ifdef HAVE_ATTR_length
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
- 0, /* tv_id */
+ TV_NONE, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
if (LABEL_P (insn))
{
rtx next;
+ bool next_is_jumptable;
/* Merge in alignments computed by compute_alignments. */
log = LABEL_TO_ALIGNMENT (insn);
max_skip = LABEL_TO_MAX_SKIP (insn);
}
- log = LABEL_ALIGN (insn);
- if (max_log < log)
+ next = next_nonnote_insn (insn);
+ next_is_jumptable = next && JUMP_TABLE_DATA_P (next);
+ if (!next_is_jumptable)
{
- max_log = log;
- max_skip = LABEL_ALIGN_MAX_SKIP;
+ log = LABEL_ALIGN (insn);
+ if (max_log < log)
+ {
+ max_log = log;
+ max_skip = LABEL_ALIGN_MAX_SKIP;
+ }
}
- next = next_nonnote_insn (insn);
/* ADDR_VECs only take room if read-only data goes into the text
section. */
- if (JUMP_TABLES_IN_TEXT_SECTION
- || readonly_data_section == text_section)
- if (next && JUMP_P (next))
- {
- rtx nextbody = PATTERN (next);
- if (GET_CODE (nextbody) == ADDR_VEC
- || GET_CODE (nextbody) == ADDR_DIFF_VEC)
- {
- log = ADDR_VEC_ALIGN (next);
- if (max_log < log)
- {
- max_log = log;
- max_skip = LABEL_ALIGN_MAX_SKIP;
- }
- }
- }
+ if ((JUMP_TABLES_IN_TEXT_SECTION
+ || readonly_data_section == text_section)
+ && next_is_jumptable)
+ {
+ log = ADDR_VEC_ALIGN (next);
+ if (max_log < log)
+ {
+ max_log = log;
+ max_skip = LABEL_ALIGN_MAX_SKIP;
+ }
+ }
LABEL_TO_ALIGNMENT (insn) = max_log;
LABEL_TO_MAX_SKIP (insn) = max_skip;
max_log = 0;
last_filename = locator_file (prologue_locator);
last_linenum = locator_line (prologue_locator);
+ last_discriminator = discriminator = 0;
high_block_linenum = high_function_linenum = last_linenum;
else
*seen |= SEEN_BB;
+ discriminator = NOTE_BASIC_BLOCK (insn)->discriminator;
+
break;
case NOTE_INSN_EH_REGION_BEG:
break;
case NOTE_INSN_EPILOGUE_BEG:
+#if defined (DWARF2_UNWIND_INFO) && defined (HAVE_epilogue)
+ if (dwarf2out_do_frame ())
+ dwarf2out_begin_epilogue (insn);
+#endif
targetm.asm_out.function_begin_epilogue (file);
break;
+ case NOTE_INSN_CFA_RESTORE_STATE:
+#if defined (DWARF2_UNWIND_INFO)
+ dwarf2out_frame_debug_restore_state ();
+#endif
+ break;
+
case NOTE_INSN_FUNCTION_BEG:
app_disable ();
(*debug_hooks->end_prologue) (last_linenum, last_filename);
app_disable ();
next = next_nonnote_insn (insn);
- if (next != 0 && JUMP_P (next))
+ /* If this label is followed by a jump-table, make sure we put
+ the label in the read-only section. Also possibly write the
+ label and jump table together. */
+ if (next != 0 && JUMP_TABLE_DATA_P (next))
{
- rtx nextbody = PATTERN (next);
-
- /* If this label is followed by a jump-table,
- make sure we put the label in the read-only section. Also
- possibly write the label and jump table together. */
-
- if (GET_CODE (nextbody) == ADDR_VEC
- || GET_CODE (nextbody) == ADDR_DIFF_VEC)
- {
#if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
- /* In this case, the case vector is being moved by the
- target, so don't output the label at all. Leave that
- to the back end macros. */
+ /* In this case, the case vector is being moved by the
+ target, so don't output the label at all. Leave that
+ to the back end macros. */
#else
- if (! JUMP_TABLES_IN_TEXT_SECTION)
- {
- int log_align;
+ if (! JUMP_TABLES_IN_TEXT_SECTION)
+ {
+ int log_align;
- switch_to_section (targetm.asm_out.function_rodata_section
- (current_function_decl));
+ switch_to_section (targetm.asm_out.function_rodata_section
+ (current_function_decl));
#ifdef ADDR_VEC_ALIGN
- log_align = ADDR_VEC_ALIGN (next);
+ log_align = ADDR_VEC_ALIGN (next);
#else
- log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
+ log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
#endif
- ASM_OUTPUT_ALIGN (file, log_align);
- }
- else
- switch_to_section (current_function_section ());
+ ASM_OUTPUT_ALIGN (file, log_align);
+ }
+ else
+ switch_to_section (current_function_section ());
#ifdef ASM_OUTPUT_CASE_LABEL
- ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
- next);
+ ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
+ next);
#else
- targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
#endif
#endif
- break;
- }
+ break;
}
if (LABEL_ALT_ENTRY_P (insn))
output_alternate_entry_point (file, insn);
note in a row. */
if (notice_source_line (insn))
{
- (*debug_hooks->source_line) (last_linenum, last_filename);
+ (*debug_hooks->source_line) (last_linenum,
+ last_filename,
+ last_discriminator);
}
if (GET_CODE (body) == ASM_INPUT)
&& GET_CODE (SET_DEST (set)) == CC0
&& insn != last_ignored_compare)
{
+ rtx src1, src2;
if (GET_CODE (SET_SRC (set)) == SUBREG)
SET_SRC (set) = alter_subreg (&SET_SRC (set));
- else if (GET_CODE (SET_SRC (set)) == COMPARE)
+
+ src1 = SET_SRC (set);
+ src2 = NULL_RTX;
+ if (GET_CODE (SET_SRC (set)) == COMPARE)
{
if (GET_CODE (XEXP (SET_SRC (set), 0)) == SUBREG)
XEXP (SET_SRC (set), 0)
if (GET_CODE (XEXP (SET_SRC (set), 1)) == SUBREG)
XEXP (SET_SRC (set), 1)
= alter_subreg (&XEXP (SET_SRC (set), 1));
+ if (XEXP (SET_SRC (set), 1)
+ == CONST0_RTX (GET_MODE (XEXP (SET_SRC (set), 0))))
+ src2 = XEXP (SET_SRC (set), 0);
}
if ((cc_status.value1 != 0
- && rtx_equal_p (SET_SRC (set), cc_status.value1))
+ && rtx_equal_p (src1, cc_status.value1))
|| (cc_status.value2 != 0
- && rtx_equal_p (SET_SRC (set), cc_status.value2)))
+ && rtx_equal_p (src1, cc_status.value2))
+ || (src2 != 0 && cc_status.value1 != 0
+ && rtx_equal_p (src2, cc_status.value1))
+ || (src2 != 0 && cc_status.value2 != 0
+ && rtx_equal_p (src2, cc_status.value2)))
{
/* Don't delete insn if it has an addressing side-effect. */
if (! FIND_REG_INC_NOTE (insn, NULL_RTX)
}
}
}
-#endif
-#ifdef HAVE_cc0
/* If this is a conditional branch, maybe modify it
if the cc's are in a nonstandard state
so that it accomplishes the same thing that it would
if (filename
&& (force_source_line
|| filename != last_filename
- || last_linenum != linenum))
+ || last_linenum != linenum
+ || last_discriminator != discriminator))
{
force_source_line = false;
last_filename = filename;
last_linenum = linenum;
+ last_discriminator = discriminator;
high_block_linenum = MAX (last_linenum, high_block_linenum);
high_function_linenum = MAX (last_linenum, high_function_linenum);
return true;
sdbout_types (NULL_TREE);
#endif
+ flag_rerun_cse_after_global_opts = 0;
reload_completed = 0;
epilogue_completed = 0;
#ifdef STACK_REGS
0 /* todo_flags_finish */
}
};
-