Commit 141719a8 by Jason Merrill

x

From-SVN: r13339
parent 1bf2b2d2
...@@ -4976,6 +4976,7 @@ save_restore_insns (store_p, large_reg, large_offset, file) ...@@ -4976,6 +4976,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
long gp_offset; long gp_offset;
long fp_offset; long fp_offset;
long end_offset; long end_offset;
rtx insn;
if (frame_pointer_needed && !BITSET_P (mask, FRAME_POINTER_REGNUM - GP_REG_FIRST)) if (frame_pointer_needed && !BITSET_P (mask, FRAME_POINTER_REGNUM - GP_REG_FIRST))
abort (); abort ();
...@@ -5019,9 +5020,10 @@ save_restore_insns (store_p, large_reg, large_offset, file) ...@@ -5019,9 +5020,10 @@ save_restore_insns (store_p, large_reg, large_offset, file)
if (file == (FILE *)0) if (file == (FILE *)0)
{ {
if (TARGET_LONG64) 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 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 else
fprintf (file, "\t%s\t%s,%s,%s\n", fprintf (file, "\t%s\t%s,%s,%s\n",
...@@ -5037,11 +5039,13 @@ save_restore_insns (store_p, large_reg, large_offset, file) ...@@ -5037,11 +5039,13 @@ save_restore_insns (store_p, large_reg, large_offset, file)
base_offset = gp_offset; base_offset = gp_offset;
if (file == (FILE *)0) 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) 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 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 else
fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n\t%s\t%s,%s,%s\n", 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) ...@@ -5067,7 +5071,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
if (store_p) 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; RTX_FRAME_RELATED_P (insn) = 1;
} }
else if (!TARGET_ABICALLS || mips_abi != ABI_32 else if (!TARGET_ABICALLS || mips_abi != ABI_32
...@@ -5133,9 +5137,10 @@ save_restore_insns (store_p, large_reg, large_offset, file) ...@@ -5133,9 +5137,10 @@ save_restore_insns (store_p, large_reg, large_offset, file)
if (file == (FILE *)0) if (file == (FILE *)0)
{ {
if (TARGET_LONG64) 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 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 else
fprintf (file, "\t%s\t%s,%s,%s\n", fprintf (file, "\t%s\t%s,%s,%s\n",
...@@ -5151,11 +5156,13 @@ save_restore_insns (store_p, large_reg, large_offset, file) ...@@ -5151,11 +5156,13 @@ save_restore_insns (store_p, large_reg, large_offset, file)
base_offset = fp_offset; base_offset = fp_offset;
if (file == (FILE *)0) 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) 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 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 else
fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n\t%s\t%s,%s,%s\n", 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) ...@@ -5183,7 +5190,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
if (store_p) 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; RTX_FRAME_RELATED_P (insn) = 1;
} }
else else
...@@ -5416,7 +5423,8 @@ mips_expand_prologue () ...@@ -5416,7 +5423,8 @@ mips_expand_prologue ()
if (tsize > 32767) if (tsize > 32767)
{ {
tmp_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM); 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; tsize_rtx = tmp_rtx;
} }
......
...@@ -3940,16 +3940,29 @@ dwarf2out_frame_debug (insn) ...@@ -3940,16 +3940,29 @@ dwarf2out_frame_debug (insn)
char *label; char *label;
rtx src, dest; rtx src, dest;
long offset; long offset;
/* The current rule for calculating the DWARF2 canonical frame address. */
static unsigned cfa_reg; static unsigned cfa_reg;
static long cfa_offset; 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) if (insn == NULL_RTX)
{ {
/* Set up state for generating call frame debug info. */ /* Set up state for generating call frame debug info. */
cfa_reg = STACK_POINTER_REGNUM; cfa_reg = STACK_POINTER_REGNUM;
cfa_offset = 0; 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; return;
} }
...@@ -3966,26 +3979,57 @@ dwarf2out_frame_debug (insn) ...@@ -3966,26 +3979,57 @@ dwarf2out_frame_debug (insn)
case REG: case REG:
/* Update the CFA rule wrt SP or FP. Make sure src is /* Update the CFA rule wrt SP or FP. Make sure src is
relative to the current CFA register. */ relative to the current CFA register. */
assert (REGNO (dest) == STACK_POINTER_REGNUM
|| frame_pointer_needed && REGNO (dest) == FRAME_POINTER_REGNUM);
switch (GET_CODE (src)) switch (GET_CODE (src))
{ {
/* Setting FP from SP. */ /* Setting FP from SP. */
case REG: case REG:
assert (cfa_reg == REGNO (src)); assert (cfa_reg == REGNO (src));
assert (REGNO (dest) == STACK_POINTER_REGNUM
|| frame_pointer_needed && REGNO (dest) == FRAME_POINTER_REGNUM);
cfa_reg = REGNO (dest); cfa_reg = REGNO (dest);
break; break;
/* Adjusting SP. */
case PLUS: case PLUS:
cfa_sp_offset -= INTVAL (XEXP (src, 1));
goto add;
case MINUS: case MINUS:
cfa_sp_offset += INTVAL (XEXP (src, 1)); if (dest == stack_pointer_rtx)
add: {
assert (REGNO (XEXP (src, 0)) == STACK_POINTER_REGNUM); /* Adjusting SP. */
if (cfa_reg == STACK_POINTER_REGNUM) switch (GET_CODE (XEXP (src, 1)))
cfa_offset = cfa_sp_offset; {
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; break;
default: default:
...@@ -4001,27 +4045,27 @@ dwarf2out_frame_debug (insn) ...@@ -4001,27 +4045,27 @@ dwarf2out_frame_debug (insn)
switch (GET_CODE (XEXP (dest, 0))) switch (GET_CODE (XEXP (dest, 0)))
{ {
/* With a push. */ /* With a push. */
case PRE_DEC:
cfa_sp_offset += GET_MODE_SIZE (GET_MODE (dest));
goto pre;
case PRE_INC: case PRE_INC:
cfa_sp_offset -= GET_MODE_SIZE (GET_MODE (dest)); case PRE_DEC:
pre: 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 (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) if (cfa_reg == STACK_POINTER_REGNUM)
cfa_offset = cfa_sp_offset; cfa_offset = cfa_store_offset;
offset = -cfa_sp_offset; offset = -cfa_store_offset;
break; break;
/* With an offset. */ /* With an offset. */
case PLUS: case PLUS:
offset = INTVAL (XEXP (XEXP (dest, 0), 1));
goto off;
case MINUS: case MINUS:
offset = -INTVAL (XEXP (XEXP (dest, 0), 1)); offset = INTVAL (XEXP (XEXP (dest, 0), 1));
off: if (GET_CODE (src) == MINUS)
assert (cfa_reg == REGNO (XEXP (XEXP (dest, 0), 0))); offset = -offset;
offset -= cfa_offset; assert (cfa_store_reg == REGNO (XEXP (XEXP (dest, 0), 0)));
offset -= cfa_store_offset;
break; break;
default: default:
...@@ -6000,12 +6044,12 @@ add_bound_info (subrange_die, bound_attr, bound) ...@@ -6000,12 +6044,12 @@ add_bound_info (subrange_die, bound_attr, bound)
/* All fixed-bounds are represented by INTEGER_CST nodes. */ /* All fixed-bounds are represented by INTEGER_CST nodes. */
case INTEGER_CST: case INTEGER_CST:
bound_value = TREE_INT_CST_LOW (bound); bound_value = TREE_INT_CST_LOW (bound);
/* TODO: we need to check for C language below, or some flag if (bound_attr == DW_AT_lower_bound
derived from the language. C implies a lower bound of 0. */ && ((is_c_family () && bound_value == 0)
if (!(bound_attr == DW_AT_lower_bound && bound_value == 0)) || (is_fortran () && bound_value == 1)))
{ /* use the default */;
add_AT_unsigned (subrange_die, bound_attr, bound_value); else
} add_AT_unsigned (subrange_die, bound_attr, bound_value);
break; break;
/* Dynamic bounds may be represented by NOP_EXPR nodes containing /* Dynamic bounds may be represented by NOP_EXPR nodes containing
...@@ -6015,34 +6059,45 @@ add_bound_info (subrange_die, bound_attr, bound) ...@@ -6015,34 +6059,45 @@ add_bound_info (subrange_die, bound_attr, bound)
/* ... fall thru... */ /* ... fall thru... */
case SAVE_EXPR: 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 /* If optimization is turned on, the SAVE_EXPRs that describe how to
access the upper bound values are essentially bogus. They only access the upper bound values are essentially bogus. They only
describe (at best) how to get at these values at the points in the 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, generated code right after they have just been computed. Worse
in the typical case, the upper bound values will not even *be* yet, in the typical case, the upper bound values will not even
computed in the optimized code, so these SAVE_EXPRs are entirely *be* computed in the optimized code, so these SAVE_EXPRs are
bogus. In order to compensate for this fact, we check here to see if entirely bogus. In order to compensate for this fact, we check
optimization is enabled, and if so, we effectively create an empty here to see if optimization is enabled, and if so, we don't add an
location description for the (unknown and unknowable) upper bound. attribute for the (unknown and unknowable) upper bound. This
This should not cause too much trouble for existing (stupid?) should not cause too much trouble for existing (stupid?)
debuggers because they have to deal with empty upper bounds location debuggers because they have to deal with empty upper bounds
descriptions anyway in order to be able to deal with incomplete array location descriptions anyway in order to be able to deal with
types. Of course an intelligent debugger (GDB?) should be able to incomplete array types. Of course an intelligent debugger (GDB?)
comprehend that a missing upper bound specification in a array type should be able to comprehend that a missing upper bound
used for a storage class `auto' local array variable indicates that specification in a array type used for a storage class `auto'
the upper bound is both unknown (at compile- time) and unknowable (at local array variable indicates that the upper bound is both
run-time) due to optimization. */ unknown (at compile- time) and unknowable (at run-time) due to
optimization. */
if (!optimize) if (!optimize)
{ {
bound_loc = mem_loc_descriptor ( bound_loc = mem_loc_descriptor
eliminate_regs (SAVE_EXPR_RTL (bound), (eliminate_regs (SAVE_EXPR_RTL (bound), 0, NULL_RTX));
0, NULL_RTX)); add_AT_loc (subrange_die, bound_attr, bound_loc);
} }
else /* else leave out the attribute. */
{
bound_loc = NULL;
}
add_AT_loc (subrange_die, bound_attr, bound_loc);
break; break;
default: default:
...@@ -6096,8 +6151,7 @@ add_subscript_info (type_die, type) ...@@ -6096,8 +6151,7 @@ add_subscript_info (type_die, type)
add_type_attribute (subrange_die, TREE_TYPE (domain), 0, 0, add_type_attribute (subrange_die, TREE_TYPE (domain), 0, 0,
type_die); 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); add_bound_info (subrange_die, DW_AT_upper_bound, upper);
} }
else else
...@@ -6741,9 +6795,8 @@ gen_formal_parameter_die (node, context_die) ...@@ -6741,9 +6795,8 @@ gen_formal_parameter_die (node, context_die)
if (DECL_ARTIFICIAL (node)) if (DECL_ARTIFICIAL (node))
add_AT_flag (parm_die, DW_AT_artificial, 1); add_AT_flag (parm_die, DW_AT_artificial, 1);
} }
if (DECL_ABSTRACT (node)) equate_decl_number_to_die (node, parm_die);
equate_decl_number_to_die (node, parm_die); if (! DECL_ABSTRACT (node))
else
add_location_or_const_value_attribute (parm_die, node); add_location_or_const_value_attribute (parm_die, node);
break; break;
...@@ -7117,7 +7170,7 @@ gen_variable_die (decl, context_die) ...@@ -7117,7 +7170,7 @@ gen_variable_die (decl, context_die)
{ {
add_abstract_origin_attribute (var_die, origin); 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); assert (get_AT_flag (old_die, DW_AT_declaration) == 1);
add_AT_die_ref (var_die, DW_AT_specification, old_die); add_AT_die_ref (var_die, DW_AT_specification, old_die);
...@@ -7157,8 +7210,7 @@ gen_variable_die (decl, context_die) ...@@ -7157,8 +7210,7 @@ gen_variable_die (decl, context_die)
if (! declaration && ! DECL_ABSTRACT (decl)) 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_location_or_const_value_attribute (var_die, decl);
add_pubname (decl, var_die); add_pubname (decl, var_die);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment