aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <merrill@gnu.org>1996-12-21 12:06:53 +0000
committerJason Merrill <merrill@gnu.org>1996-12-21 12:06:53 +0000
commit141719a8d7441a64d057e5095e7c96c19cf2aa7e (patch)
treef075334643348fce480f1e4b050189c675bb48f9
parent1bf2b2d2a86ccae42e47a88be0c3cae16ecf352f (diff)
downloadgcc-141719a8d7441a64d057e5095e7c96c19cf2aa7e.zip
gcc-141719a8d7441a64d057e5095e7c96c19cf2aa7e.tar.gz
gcc-141719a8d7441a64d057e5095e7c96c19cf2aa7e.tar.bz2
x
From-SVN: r13339
-rw-r--r--gcc/config/mips/mips.c34
-rw-r--r--gcc/dwarf2out.c174
2 files changed, 134 insertions, 74 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index cacbf1f..eaf24c2 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -4976,6 +4976,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
long gp_offset;
long fp_offset;
long end_offset;
+ rtx insn;
if (frame_pointer_needed && !BITSET_P (mask, FRAME_POINTER_REGNUM - GP_REG_FIRST))
abort ();
@@ -5019,9 +5020,10 @@ save_restore_insns (store_p, large_reg, large_offset, file)
if (file == (FILE *)0)
{
if (TARGET_LONG64)
- emit_insn (gen_adddi3 (base_reg_rtx, large_reg, stack_pointer_rtx));
+ insn = emit_insn (gen_adddi3 (base_reg_rtx, large_reg, stack_pointer_rtx));
else
- emit_insn (gen_addsi3 (base_reg_rtx, large_reg, stack_pointer_rtx));
+ insn = emit_insn (gen_addsi3 (base_reg_rtx, large_reg, stack_pointer_rtx));
+ RTX_FRAME_RELATED_P (insn) = 1;
}
else
fprintf (file, "\t%s\t%s,%s,%s\n",
@@ -5037,11 +5039,13 @@ save_restore_insns (store_p, large_reg, large_offset, file)
base_offset = gp_offset;
if (file == (FILE *)0)
{
- emit_move_insn (base_reg_rtx, GEN_INT (gp_offset));
+ insn = emit_move_insn (base_reg_rtx, GEN_INT (gp_offset));
+ RTX_FRAME_RELATED_P (insn) = 1;
if (TARGET_LONG64)
- emit_insn (gen_adddi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
+ insn = emit_insn (gen_adddi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
else
- emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
+ insn = emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
+ RTX_FRAME_RELATED_P (insn) = 1;
}
else
fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n\t%s\t%s,%s,%s\n",
@@ -5067,7 +5071,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
if (store_p)
{
- rtx insn = emit_move_insn (mem_rtx, reg_rtx);
+ insn = emit_move_insn (mem_rtx, reg_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
}
else if (!TARGET_ABICALLS || mips_abi != ABI_32
@@ -5133,9 +5137,10 @@ save_restore_insns (store_p, large_reg, large_offset, file)
if (file == (FILE *)0)
{
if (TARGET_LONG64)
- emit_insn (gen_adddi3 (base_reg_rtx, large_reg, stack_pointer_rtx));
+ insn = emit_insn (gen_adddi3 (base_reg_rtx, large_reg, stack_pointer_rtx));
else
- emit_insn (gen_addsi3 (base_reg_rtx, large_reg, stack_pointer_rtx));
+ insn = emit_insn (gen_addsi3 (base_reg_rtx, large_reg, stack_pointer_rtx));
+ RTX_FRAME_RELATED_P (insn) = 1;
}
else
fprintf (file, "\t%s\t%s,%s,%s\n",
@@ -5151,11 +5156,13 @@ save_restore_insns (store_p, large_reg, large_offset, file)
base_offset = fp_offset;
if (file == (FILE *)0)
{
- emit_move_insn (base_reg_rtx, GEN_INT (fp_offset));
+ insn = emit_move_insn (base_reg_rtx, GEN_INT (fp_offset));
+ RTX_FRAME_RELATED_P (insn) = 1;
if (TARGET_LONG64)
- emit_insn (gen_adddi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
+ insn = emit_insn (gen_adddi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
else
- emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
+ insn = emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
+ RTX_FRAME_RELATED_P (insn) = 1;
}
else
fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n\t%s\t%s,%s,%s\n",
@@ -5183,7 +5190,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
if (store_p)
{
- rtx insn = emit_move_insn (mem_rtx, reg_rtx);
+ insn = emit_move_insn (mem_rtx, reg_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
}
else
@@ -5416,7 +5423,8 @@ mips_expand_prologue ()
if (tsize > 32767)
{
tmp_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM);
- emit_move_insn (tmp_rtx, tsize_rtx);
+ insn = emit_move_insn (tmp_rtx, tsize_rtx);
+ RTX_FRAME_RELATED_P (insn) = 1;
tsize_rtx = tmp_rtx;
}
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 99007b3..811977c 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3940,16 +3940,29 @@ dwarf2out_frame_debug (insn)
char *label;
rtx src, dest;
long offset;
+
+ /* The current rule for calculating the DWARF2 canonical frame address. */
static unsigned cfa_reg;
static long cfa_offset;
- static long cfa_sp_offset;
+
+ /* The register used for saving registers to the stack, and its offset
+ from the CFA. */
+ static unsigned cfa_store_reg;
+ static long cfa_store_offset;
+
+ /* A temporary register used in adjusting SP or setting up the store_reg. */
+ static unsigned cfa_temp_reg;
+ static long cfa_temp_value;
if (insn == NULL_RTX)
{
/* Set up state for generating call frame debug info. */
cfa_reg = STACK_POINTER_REGNUM;
cfa_offset = 0;
- cfa_sp_offset = 0;
+ cfa_store_reg = STACK_POINTER_REGNUM;
+ cfa_store_offset = 0;
+ cfa_temp_reg = -1;
+ cfa_temp_value = 0;
return;
}
@@ -3966,26 +3979,57 @@ dwarf2out_frame_debug (insn)
case REG:
/* Update the CFA rule wrt SP or FP. Make sure src is
relative to the current CFA register. */
- assert (REGNO (dest) == STACK_POINTER_REGNUM
- || frame_pointer_needed && REGNO (dest) == FRAME_POINTER_REGNUM);
switch (GET_CODE (src))
{
/* Setting FP from SP. */
case REG:
assert (cfa_reg == REGNO (src));
+ assert (REGNO (dest) == STACK_POINTER_REGNUM
+ || frame_pointer_needed && REGNO (dest) == FRAME_POINTER_REGNUM);
cfa_reg = REGNO (dest);
break;
- /* Adjusting SP. */
case PLUS:
- cfa_sp_offset -= INTVAL (XEXP (src, 1));
- goto add;
case MINUS:
- cfa_sp_offset += INTVAL (XEXP (src, 1));
- add:
- assert (REGNO (XEXP (src, 0)) == STACK_POINTER_REGNUM);
- if (cfa_reg == STACK_POINTER_REGNUM)
- cfa_offset = cfa_sp_offset;
+ if (dest == stack_pointer_rtx)
+ {
+ /* Adjusting SP. */
+ switch (GET_CODE (XEXP (src, 1)))
+ {
+ case CONST_INT:
+ offset = INTVAL (XEXP (src, 1));
+ break;
+ case REG:
+ assert (REGNO (XEXP (src, 1)) == cfa_temp_reg);
+ offset = cfa_temp_value;
+ break;
+ default:
+ abort ();
+ }
+ if (GET_CODE (src) == PLUS)
+ offset = -offset;
+ if (cfa_reg == STACK_POINTER_REGNUM)
+ cfa_offset += offset;
+ if (cfa_store_reg == STACK_POINTER_REGNUM)
+ cfa_store_offset += offset;
+ assert (XEXP (src, 0) == stack_pointer_rtx);
+ }
+ else
+ {
+ /* Initializing the store base register. */
+ assert (GET_CODE (src) == PLUS);
+ assert (XEXP (src, 1) == stack_pointer_rtx);
+ assert (GET_CODE (XEXP (src, 0)) == REG
+ && REGNO (XEXP (src, 0)) == cfa_temp_reg);
+ assert (cfa_store_reg == STACK_POINTER_REGNUM);
+ cfa_store_reg = REGNO (dest);
+ cfa_store_offset -= cfa_temp_value;
+ }
+ break;
+
+ case CONST_INT:
+ cfa_temp_reg = REGNO (dest);
+ cfa_temp_value = INTVAL (src);
break;
default:
@@ -4001,27 +4045,27 @@ dwarf2out_frame_debug (insn)
switch (GET_CODE (XEXP (dest, 0)))
{
/* With a push. */
- case PRE_DEC:
- cfa_sp_offset += GET_MODE_SIZE (GET_MODE (dest));
- goto pre;
case PRE_INC:
- cfa_sp_offset -= GET_MODE_SIZE (GET_MODE (dest));
- pre:
+ case PRE_DEC:
+ offset = GET_MODE_SIZE (GET_MODE (dest));
+ if (GET_CODE (src) == PRE_INC)
+ offset = -offset;
assert (REGNO (XEXP (XEXP (dest, 0), 0)) == STACK_POINTER_REGNUM);
+ assert (cfa_store_reg == STACK_POINTER_REGNUM);
+ cfa_store_offset += offset;
if (cfa_reg == STACK_POINTER_REGNUM)
- cfa_offset = cfa_sp_offset;
- offset = -cfa_sp_offset;
+ cfa_offset = cfa_store_offset;
+ offset = -cfa_store_offset;
break;
/* With an offset. */
case PLUS:
- offset = INTVAL (XEXP (XEXP (dest, 0), 1));
- goto off;
case MINUS:
- offset = -INTVAL (XEXP (XEXP (dest, 0), 1));
- off:
- assert (cfa_reg == REGNO (XEXP (XEXP (dest, 0), 0)));
- offset -= cfa_offset;
+ offset = INTVAL (XEXP (XEXP (dest, 0), 1));
+ if (GET_CODE (src) == MINUS)
+ offset = -offset;
+ assert (cfa_store_reg == REGNO (XEXP (XEXP (dest, 0), 0)));
+ offset -= cfa_store_offset;
break;
default:
@@ -6000,12 +6044,12 @@ add_bound_info (subrange_die, bound_attr, bound)
/* All fixed-bounds are represented by INTEGER_CST nodes. */
case INTEGER_CST:
bound_value = TREE_INT_CST_LOW (bound);
- /* TODO: we need to check for C language below, or some flag
- derived from the language. C implies a lower bound of 0. */
- if (!(bound_attr == DW_AT_lower_bound && bound_value == 0))
- {
- add_AT_unsigned (subrange_die, bound_attr, bound_value);
- }
+ if (bound_attr == DW_AT_lower_bound
+ && ((is_c_family () && bound_value == 0)
+ || (is_fortran () && bound_value == 1)))
+ /* use the default */;
+ else
+ add_AT_unsigned (subrange_die, bound_attr, bound_value);
break;
/* Dynamic bounds may be represented by NOP_EXPR nodes containing
@@ -6015,34 +6059,45 @@ add_bound_info (subrange_die, bound_attr, bound)
/* ... fall thru... */
case SAVE_EXPR:
+ /* Handle the simple case of `int ar[i];'. */
+ if (bound_attr == DW_AT_upper_bound && is_c_family ()
+ && TREE_CODE (TREE_OPERAND (bound, 0)) == MINUS_EXPR)
+ {
+ tree t = TREE_OPERAND (bound, 0);
+ if (integer_onep (TREE_OPERAND (bound, 1)))
+ t = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL)
+ {
+ add_AT_die_ref (subrange_die, DW_AT_count, lookup_decl_die (t));
+ return;
+ }
+ }
+
/* If optimization is turned on, the SAVE_EXPRs that describe how to
access the upper bound values are essentially bogus. They only
describe (at best) how to get at these values at the points in the
- generated code right after they have just been computed. Worse yet,
- in the typical case, the upper bound values will not even *be*
- computed in the optimized code, so these SAVE_EXPRs are entirely
- bogus. In order to compensate for this fact, we check here to see if
- optimization is enabled, and if so, we effectively create an empty
- location description for the (unknown and unknowable) upper bound.
- This should not cause too much trouble for existing (stupid?)
- debuggers because they have to deal with empty upper bounds location
- descriptions anyway in order to be able to deal with incomplete array
- types. Of course an intelligent debugger (GDB?) should be able to
- comprehend that a missing upper bound specification in a array type
- used for a storage class `auto' local array variable indicates that
- the upper bound is both unknown (at compile- time) and unknowable (at
- run-time) due to optimization. */
+ generated code right after they have just been computed. Worse
+ yet, in the typical case, the upper bound values will not even
+ *be* computed in the optimized code, so these SAVE_EXPRs are
+ entirely bogus. In order to compensate for this fact, we check
+ here to see if optimization is enabled, and if so, we don't add an
+ attribute for the (unknown and unknowable) upper bound. This
+ should not cause too much trouble for existing (stupid?)
+ debuggers because they have to deal with empty upper bounds
+ location descriptions anyway in order to be able to deal with
+ incomplete array types. Of course an intelligent debugger (GDB?)
+ should be able to comprehend that a missing upper bound
+ specification in a array type used for a storage class `auto'
+ local array variable indicates that the upper bound is both
+ unknown (at compile- time) and unknowable (at run-time) due to
+ optimization. */
if (!optimize)
{
- bound_loc = mem_loc_descriptor (
- eliminate_regs (SAVE_EXPR_RTL (bound),
- 0, NULL_RTX));
+ bound_loc = mem_loc_descriptor
+ (eliminate_regs (SAVE_EXPR_RTL (bound), 0, NULL_RTX));
+ add_AT_loc (subrange_die, bound_attr, bound_loc);
}
- else
- {
- bound_loc = NULL;
- }
- add_AT_loc (subrange_die, bound_attr, bound_loc);
+ /* else leave out the attribute. */
break;
default:
@@ -6096,8 +6151,7 @@ add_subscript_info (type_die, type)
add_type_attribute (subrange_die, TREE_TYPE (domain), 0, 0,
type_die);
- if (! is_c_family () && ! is_fortran ())
- add_bound_info (subrange_die, DW_AT_lower_bound, lower);
+ add_bound_info (subrange_die, DW_AT_lower_bound, lower);
add_bound_info (subrange_die, DW_AT_upper_bound, upper);
}
else
@@ -6741,9 +6795,8 @@ gen_formal_parameter_die (node, context_die)
if (DECL_ARTIFICIAL (node))
add_AT_flag (parm_die, DW_AT_artificial, 1);
}
- if (DECL_ABSTRACT (node))
- equate_decl_number_to_die (node, parm_die);
- else
+ equate_decl_number_to_die (node, parm_die);
+ if (! DECL_ABSTRACT (node))
add_location_or_const_value_attribute (parm_die, node);
break;
@@ -7117,7 +7170,7 @@ gen_variable_die (decl, context_die)
{
add_abstract_origin_attribute (var_die, origin);
}
- else if (old_die)
+ else if (old_die && TREE_STATIC (decl))
{
assert (get_AT_flag (old_die, DW_AT_declaration) == 1);
add_AT_die_ref (var_die, DW_AT_specification, old_die);
@@ -7157,8 +7210,7 @@ gen_variable_die (decl, context_die)
if (! declaration && ! DECL_ABSTRACT (decl))
{
- if (TREE_STATIC (decl))
- equate_decl_number_to_die (decl, var_die);
+ equate_decl_number_to_die (decl, var_die);
add_location_or_const_value_attribute (var_die, decl);
add_pubname (decl, var_die);
}