OSDN Git Service

* reorg.c (fill_slots_from_thread): Check side_effects_p when
[pf3gnuchains/gcc-fork.git] / gcc / frame.c
index 717849f..cfd979b 100644 (file)
@@ -610,12 +610,14 @@ find_fde (void *pc)
        {
          fde **p = ob->fde_array;
          
-         for (; *p; ++p)
+         do
            {
              f = search_fdes (*p, pc);
              if (f)
                break;
+             p++;
            }
+         while (*p);
        }
       else
        f = search_fdes (ob->fde_begin, pc);
@@ -692,9 +694,16 @@ execute_cfa_insn (void *p, struct frame_state_internal *state,
     {
       reg = (insn & 0x3f);
       p = decode_uleb128 (p, &offset);
-      offset *= info->data_align;
-      state->s.saved[reg] = REG_SAVED_OFFSET;
-      state->s.reg_or_offset[reg] = offset;
+      if (reg == state->s.cfa_reg)
+       /* Don't record anything about this register; it's only used to
+          reload SP in the epilogue.  We don't want to copy in SP
+          values for outer frames; we handle restoring SP specially.  */;
+      else
+       {
+         offset *= info->data_align;
+         state->s.saved[reg] = REG_SAVED_OFFSET;
+         state->s.reg_or_offset[reg] = offset;
+       }
     }
   else if (insn & DW_CFA_restore)
     {
@@ -723,9 +732,14 @@ execute_cfa_insn (void *p, struct frame_state_internal *state,
     case DW_CFA_offset_extended:
       p = decode_uleb128 (p, &reg);
       p = decode_uleb128 (p, &offset);
-      offset *= info->data_align;
-      state->s.saved[reg] = REG_SAVED_OFFSET;
-      state->s.reg_or_offset[reg] = offset;
+      if (reg == state->s.cfa_reg)
+       /* Don't record anything; see above.  */;
+      else
+       {
+         offset *= info->data_align;
+         state->s.saved[reg] = REG_SAVED_OFFSET;
+         state->s.reg_or_offset[reg] = offset;
+       }
       break;
     case DW_CFA_restore_extended:
       p = decode_uleb128 (p, &reg);
@@ -793,6 +807,14 @@ execute_cfa_insn (void *p, struct frame_state_internal *state,
       state->s.args_size = offset;
       break;
 
+    case DW_CFA_GNU_negative_offset_extended:
+      p = decode_uleb128 (p, &reg);
+      p = decode_uleb128 (p, &offset);
+      offset *= info->data_align;
+      state->s.saved[reg] = REG_SAVED_OFFSET;
+      state->s.reg_or_offset[reg] = -offset;
+      break;
+
     default:
       abort ();
     }