dwarf2.h (DW_OP_call_ref): Rename from DW_OP_calli.

* dwarf2.h (DW_OP_call_ref): Rename from DW_OP_calli.
        (DW_OP_GNU_push_tls_address): New.
        (DW_OP_lo_user): Fix.
        * dwarf2out.c (INTERNAL_DW_OP_tls_addr): New.
        (dwarf_stack_op_name): Handle it, plus other dwarf3 opcodes.
        (size_of_loc_descr): Likewise.
        (output_loc_operands): Handle INTERNAL_DW_OP_tls_addr.
        (add_AT_location_description): Take a dw_loc_descr_ref not an rtx.
        (loc_descriptor_from_tree): Handle TLS variables.
        (rtl_for_decl_location): Do avoid_constant_pool_reference here ...
        (add_location_or_const_value_attribute): ... not here.  Defer
        to loc_descriptor_from_tree for TLS variables.

        * config/i386/i386.h (ASM_OUTPUT_DWARF_DTPREL): New.
        * config/i386/i386.c (i386_output_dwarf_dtprel): New.
        * config/i386/i386-protos.h: Update.

From-SVN: r56957
This commit is contained in:
Richard Henderson 2002-09-08 11:36:54 -07:00 committed by Richard Henderson
parent 7df988780b
commit b920346356
6 changed files with 166 additions and 22 deletions

View File

@ -1,3 +1,22 @@
2002-09-08 Richard Henderson <rth@redhat.com>
* dwarf2.h (DW_OP_call_ref): Rename from DW_OP_calli.
(DW_OP_GNU_push_tls_address): New.
(DW_OP_lo_user): Fix.
* dwarf2out.c (INTERNAL_DW_OP_tls_addr): New.
(dwarf_stack_op_name): Handle it, plus other dwarf3 opcodes.
(size_of_loc_descr): Likewise.
(output_loc_operands): Handle INTERNAL_DW_OP_tls_addr.
(add_AT_location_description): Take a dw_loc_descr_ref not an rtx.
(loc_descriptor_from_tree): Handle TLS variables.
(rtl_for_decl_location): Do avoid_constant_pool_reference here ...
(add_location_or_const_value_attribute): ... not here. Defer
to loc_descriptor_from_tree for TLS variables.
* config/i386/i386.h (ASM_OUTPUT_DWARF_DTPREL): New.
* config/i386/i386.c (i386_output_dwarf_dtprel): New.
* config/i386/i386-protos.h: Update.
2002-09-08 Roger Sayle <roger@eyesopen.com>
PR optimization/6405

View File

@ -110,6 +110,7 @@ extern const char *output_fix_trunc PARAMS ((rtx, rtx*));
extern const char *output_fp_compare PARAMS ((rtx, rtx*, int, int));
extern void i386_dwarf_output_addr_const PARAMS ((FILE*, rtx));
extern void i386_output_dwarf_dtprel PARAMS ((FILE*, int, rtx));
extern rtx i386_simplify_dwarf_addr PARAMS ((rtx));
extern void ix86_expand_clear PARAMS ((rtx));

View File

@ -5956,6 +5956,33 @@ i386_dwarf_output_addr_const (file, x)
fputc ('\n', file);
}
/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
We need to emit DTP-relative relocations. */
void
i386_output_dwarf_dtprel (file, size, x)
FILE *file;
int size;
rtx x;
{
switch (size)
{
case 4:
fputs (ASM_LONG, file);
break;
case 8:
#ifdef ASM_QUAD
fputs (ASM_QUAD, file);
break;
#endif
default:
abort ();
}
output_addr_const (file, x);
fputs ("@DTPOFF", file);
}
/* In the name of slightly smaller debug output, and to cater to
general assembler losage, recognize PIC+GOTOFF and turn it back
into a direct symbol reference. */

View File

@ -3021,6 +3021,13 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
#define ASM_SIMPLIFY_DWARF_ADDR(X) \
i386_simplify_dwarf_addr (X)
/* Emit a dtp-relative reference to a TLS variable. */
#ifdef HAVE_AS_TLS
#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
i386_output_dwarf_dtprel (FILE, SIZE, X)
#endif
/* Switch to init or fini section via SECTION_OP, emit a call to FUNC,
and switch back. For x86 we do this only to save a few bytes that
would otherwise be unused in the text section. */

View File

@ -399,10 +399,12 @@ enum dwarf_location_atom
DW_OP_push_object_address = 0x97,
DW_OP_call2 = 0x98,
DW_OP_call4 = 0x99,
DW_OP_calli = 0x9a
DW_OP_call_ref = 0x9a,
/* GNU extensions. */
DW_OP_GNU_push_tls_address = 0xe0
};
#define DW_OP_lo_user 0x80 /* Implementation-defined range start. */
#define DW_OP_lo_user 0xe0 /* Implementation-defined range start. */
#define DW_OP_hi_user 0xff /* Implementation-defined range end. */
/* Type encodings. */

View File

@ -2182,6 +2182,11 @@ dwarf2out_frame_finish ()
/* And now, the subset of the debugging information support code necessary
for emitting location expressions. */
/* We need some way to distinguish DW_OP_addr with a direct symbol
relocation from DW_OP_addr with a dtp-relative symbol relocation. */
#define INTERNAL_DW_OP_tls_addr (0x100 + DW_OP_addr)
typedef struct dw_val_struct *dw_val_ref;
typedef struct die_struct *dw_die_ref;
typedef struct dw_loc_descr_struct *dw_loc_descr_ref;
@ -2307,6 +2312,7 @@ dwarf_stack_op_name (op)
switch (op)
{
case DW_OP_addr:
case INTERNAL_DW_OP_tls_addr:
return "DW_OP_addr";
case DW_OP_deref:
return "DW_OP_deref";
@ -2596,6 +2602,16 @@ dwarf_stack_op_name (op)
return "DW_OP_xderef_size";
case DW_OP_nop:
return "DW_OP_nop";
case DW_OP_push_object_address:
return "DW_OP_push_object_address";
case DW_OP_call2:
return "DW_OP_call2";
case DW_OP_call4:
return "DW_OP_call4";
case DW_OP_call_ref:
return "DW_OP_call_ref";
case DW_OP_GNU_push_tls_address:
return "DW_OP_GNU_push_tls_address";
default:
return "OP_<unknown>";
}
@ -2653,6 +2669,7 @@ size_of_loc_descr (loc)
switch (loc->dw_loc_opc)
{
case DW_OP_addr:
case INTERNAL_DW_OP_tls_addr:
size += DWARF2_ADDR_SIZE;
break;
case DW_OP_const1u:
@ -2738,6 +2755,15 @@ size_of_loc_descr (loc)
case DW_OP_xderef_size:
size += 1;
break;
case DW_OP_call2:
size += 2;
break;
case DW_OP_call4:
size += 4;
break;
case DW_OP_call_ref:
size += DWARF2_ADDR_SIZE;
break;
default:
break;
}
@ -2887,6 +2913,17 @@ output_loc_operands (loc)
case DW_OP_xderef_size:
dw2_asm_output_data (1, val1->v.val_int, NULL);
break;
case INTERNAL_DW_OP_tls_addr:
#ifdef ASM_OUTPUT_DWARF_DTPREL
ASM_OUTPUT_DWARF_DTPREL (asm_out_file, DWARF2_ADDR_SIZE,
val1->v.val_addr);
fputc ('\n', asm_out_file);
#else
abort ();
#endif
break;
default:
/* Other codes have no operands. */
break;
@ -3590,7 +3627,8 @@ static unsigned int simple_decl_align_in_bits PARAMS ((tree));
static unsigned HOST_WIDE_INT simple_type_size_in_bits PARAMS ((tree));
static HOST_WIDE_INT field_byte_offset PARAMS ((tree));
static void add_AT_location_description PARAMS ((dw_die_ref,
enum dwarf_attribute, rtx));
enum dwarf_attribute,
dw_loc_descr_ref));
static void add_data_member_location_attribute PARAMS ((dw_die_ref, tree));
static void add_const_value_attribute PARAMS ((dw_die_ref, rtx));
static rtx rtl_for_decl_location PARAMS ((tree));
@ -8015,6 +8053,42 @@ loc_descriptor_from_tree (loc, addressp)
: 0);
case VAR_DECL:
if (DECL_THREAD_LOCAL (loc))
{
rtx rtl;
#ifndef ASM_OUTPUT_DWARF_DTPREL
/* If this is not defined, we have no way to emit the data. */
return 0;
#endif
/* The way DW_OP_GNU_push_tls_address is specified, we can only
look up addresses of objects in the current module. */
if (! (*targetm.binds_local_p) (loc))
return 0;
rtl = rtl_for_decl_location (loc);
if (rtl == NULL_RTX)
return 0;
if (GET_CODE (rtl) != MEM)
return 0;
rtl = XEXP (rtl, 0);
if (! CONSTANT_P (rtl))
return 0;
ret = new_loc_descr (INTERNAL_DW_OP_tls_addr, 0, 0);
ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
ret->dw_loc_oprnd1.v.val_addr = rtl;
ret1 = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0);
add_loc_descr (&ret, ret1);
indirect_p = 1;
break;
}
/* FALLTHRU */
case PARM_DECL:
{
rtx rtl = rtl_for_decl_location (loc);
@ -8497,14 +8571,12 @@ field_byte_offset (decl)
whole parameters. Note that the location attributes for struct fields are
generated by the routine `data_member_location_attribute' below. */
static void
add_AT_location_description (die, attr_kind, rtl)
static inline void
add_AT_location_description (die, attr_kind, descr)
dw_die_ref die;
enum dwarf_attribute attr_kind;
rtx rtl;
dw_loc_descr_ref descr;
{
dw_loc_descr_ref descr = loc_descriptor (rtl);
if (descr != 0)
add_AT_loc (die, attr_kind, descr);
}
@ -8929,6 +9001,13 @@ rtl_for_decl_location (decl)
if (rtl)
rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
#endif
/* If we don't look past the constant pool, we risk emitting a
reference to a constant pool entry that isn't referenced from
code, and thus is not emitted. */
if (rtl)
rtl = avoid_constant_pool_reference (rtl);
return rtl;
}
@ -8949,6 +9028,7 @@ add_location_or_const_value_attribute (die, decl)
tree decl;
{
rtx rtl;
dw_loc_descr_ref descr;
if (TREE_CODE (decl) == ERROR_MARK)
return;
@ -8959,16 +9039,11 @@ add_location_or_const_value_attribute (die, decl)
if (rtl == NULL_RTX)
return;
/* If we don't look past the constant pool, we risk emitting a
reference to a constant pool entry that isn't referenced from
code, and thus is not emitted. */
rtl = avoid_constant_pool_reference (rtl);
switch (GET_CODE (rtl))
{
case ADDRESSOF:
/* The address of a variable that was optimized away; don't emit
anything. */
/* The address of a variable that was optimized away;
don't emit anything. */
break;
case CONST_INT:
@ -8983,12 +9058,24 @@ add_location_or_const_value_attribute (die, decl)
break;
case MEM:
case REG:
case SUBREG:
case CONCAT:
add_AT_location_description (die, DW_AT_location, rtl);
if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
{
/* Need loc_descriptor_from_tree since that's where we know
how to handle TLS variables. Want the object's address
since the top-level DW_AT_location assumes such. See
the confusion in loc_descriptor for reference. */
descr = loc_descriptor_from_tree (decl, 1);
}
else
{
case REG:
case SUBREG:
case CONCAT:
descr = loc_descriptor (rtl);
}
add_AT_location_description (die, DW_AT_location, descr);
break;
default:
abort ();
}
@ -9120,7 +9207,8 @@ add_bound_info (subrange_die, bound_attr, bound)
add_AT_flag (decl_die, DW_AT_artificial, 1);
add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
add_AT_location_description (decl_die, DW_AT_location, loc);
add_AT_location_description (decl_die, DW_AT_location,
loc_descriptor (loc));
add_AT_die_ref (subrange_die, bound_attr, decl_die);
}
@ -10325,7 +10413,7 @@ gen_subprogram_die (decl, context_die)
is not part of the state saved/restored for inline functions. */
if (current_function_needs_context)
add_AT_location_description (subr_die, DW_AT_static_link,
lookup_static_chain (decl));
loc_descriptor (lookup_static_chain (decl)));
#endif
}