re PR target/14619 (Incorrect Dwarf 2 information in function prologue)
[gcc.git] / gcc / config / cris / cris.c
index 4756f8ca02c3986306deae4419ad9184ef0fa5ad..3599e2dae05e2e425b45908e616541ecdd445675 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for GCC.  Part of the machine description for CRIS.
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
    Contributed by Axis Communications.  Written by Hans-Peter Nilsson.
 
@@ -656,6 +656,10 @@ cris_fatal (char *arg)
   return 0;
 }
 
+/* This variable belongs to cris_target_asm_function_prologue but must
+   be located outside it for GTY reasons.  */
+static GTY(()) unsigned long cfa_label_num = 0;
+
 /* Textual function prologue.  */
 
 static void
@@ -670,7 +674,7 @@ cris_target_asm_function_prologue (FILE *file, HOST_WIDE_INT size)
   int framesize;
   int faked_args_size = 0;
   int cfa_write_offset = 0;
-  char *cfa_label = NULL;
+  static char cfa_label[30];
   int return_address_on_stack
     = regs_ever_live[CRIS_SRP_REGNUM]
     || cfun->machine->needs_return_address_on_stack != 0;
@@ -723,7 +727,8 @@ cris_target_asm_function_prologue (FILE *file, HOST_WIDE_INT size)
          cfa_offset += cris_initial_frame_pointer_offset ();
        }
 
-      cfa_label = dwarf2out_cfi_label ();
+      ASM_GENERATE_INTERNAL_LABEL (cfa_label, "LCFIT",
+                                  cfa_label_num++);
       dwarf2out_def_cfa (cfa_label, cfa_reg, cfa_offset);
 
       cfa_write_offset = - faked_args_size - 4;
@@ -921,6 +926,9 @@ cris_target_asm_function_prologue (FILE *file, HOST_WIDE_INT size)
             reg_names[PIC_OFFSET_TABLE_REGNUM],
             reg_names[PIC_OFFSET_TABLE_REGNUM]);
 
+  if (doing_dwarf)
+    ASM_OUTPUT_LABEL (file, cfa_label);
+
   if (TARGET_PDEBUG)
     fprintf (file,
             "; parm #%d @ %d; frame " HOST_WIDE_INT_PRINT_DEC
@@ -1834,13 +1842,11 @@ cris_notice_update_cc (rtx exp, rtx insn)
       if (GET_CODE (exp) == SET)
        {
          if (cc_status.value1
-             && cris_reg_overlap_mentioned_p (SET_DEST (exp),
-                                            cc_status.value1))
+             && modified_in_p (cc_status.value1, insn))
            cc_status.value1 = 0;
 
          if (cc_status.value2
-             && cris_reg_overlap_mentioned_p (SET_DEST (exp),
-                                            cc_status.value2))
+             && modified_in_p (cc_status.value2, insn))
            cc_status.value2 = 0;
        }
       return;
@@ -1970,14 +1976,12 @@ cris_notice_update_cc (rtx exp, rtx insn)
                {
                  /* There's no CC0 change when clearing a register or
                     memory.  Just check for overlap.  */
-                 if ((cc_status.value1
-                      && cris_reg_overlap_mentioned_p (SET_DEST (exp),
-                                                       cc_status.value1)))
+                 if (cc_status.value1
+                     && modified_in_p (cc_status.value1, insn))
                    cc_status.value1 = 0;
 
-                 if ((cc_status.value2
-                      && cris_reg_overlap_mentioned_p (SET_DEST (exp),
-                                                       cc_status.value2)))
+                 if (cc_status.value2
+                     && modified_in_p (cc_status.value2, insn))
                    cc_status.value2 = 0;
 
                  return;
@@ -2009,14 +2013,12 @@ cris_notice_update_cc (rtx exp, rtx insn)
            {
              /* When SET to MEM, then CC is not changed (except for
                 overlap).  */
-             if ((cc_status.value1
-                  && cris_reg_overlap_mentioned_p (SET_DEST (exp),
-                                                   cc_status.value1)))
+             if (cc_status.value1
+                 && modified_in_p (cc_status.value1, insn))
                cc_status.value1 = 0;
 
-             if ((cc_status.value2
-                  && cris_reg_overlap_mentioned_p (SET_DEST (exp),
-                                                   cc_status.value2)))
+             if (cc_status.value2
+                 && modified_in_p (cc_status.value2, insn))
                cc_status.value2 = 0;
 
              return;
@@ -2053,31 +2055,11 @@ cris_notice_update_cc (rtx exp, rtx insn)
                  /* For "move.S rz,[rx=ry+o]" and "clear.S [rx=ry+o]",
                     say flags are not changed, except for overlap.  */
                  if (cc_status.value1
-                     && cris_reg_overlap_mentioned_p (XEXP
-                                                      (XVECEXP
-                                                       (exp, 0, 0), 0),
-                                                      cc_status.value1))
+                     && modified_in_p (cc_status.value1, insn))
                    cc_status.value1 = 0;
 
-                 if (cc_status.value1
-                     && cris_reg_overlap_mentioned_p (XEXP
-                                                      (XVECEXP
-                                                       (exp, 0, 1), 0),
-                                                      cc_status.value1))
-                   cc_status.value1 = 0;
-
-                 if (cc_status.value2
-                     && cris_reg_overlap_mentioned_p (XEXP
-                                                      (XVECEXP
-                                                       (exp, 0, 0), 0),
-                                                      cc_status.value2))
-                   cc_status.value2 = 0;
-
                  if (cc_status.value2
-                     && cris_reg_overlap_mentioned_p (XEXP
-                                                      (XVECEXP
-                                                       (exp, 0, 1), 0),
-                                                      cc_status.value2))
+                     && modified_in_p (cc_status.value2, insn))
                    cc_status.value2 = 0;
 
                  return;