* Makefile.am (ehopt.o): Add struc-symbol.h.

* Makefile.in: Regenerated.
	* ehopt.c: Include struc-symbol.h.
	(check_eh_frame): For very small O_constant DW_CFA_advance_loc4
	create correct DW_CFA_advance_loc.  Handle O_subtract only
	for code alignment factor 1, otherwise handle O_divide or
	O_right_shift of O_subtract and O_constant.
	(eh_frame_estimate_size_before_relax): Always divide by ca.
	(eh_frame_convert_frag): Likewise.

	* dw2gencfi.c (output_cfi_insn): Scale DW_CFA_advance_loc1,
	DW_CFA_advance_loc2 and DW_CFA_advance_loc4 outputs.
This commit is contained in:
Jakub Jelinek 2008-11-28 21:28:28 +00:00
parent 3aa3176b2d
commit 395e834521
5 changed files with 66 additions and 30 deletions

View file

@ -1,3 +1,20 @@
2008-11-28 Jakub Jelinek <jakub@redhat.com>
* Makefile.am (ehopt.o): Add struc-symbol.h.
* Makefile.in: Regenerated.
* ehopt.c: Include struc-symbol.h.
(check_eh_frame): For very small O_constant DW_CFA_advance_loc4
create correct DW_CFA_advance_loc. Handle O_subtract only
for code alignment factor 1, otherwise handle O_divide or
O_right_shift of O_subtract and O_constant.
(eh_frame_estimate_size_before_relax): Always divide by ca.
(eh_frame_convert_frag): Likewise.
2008-11-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* dw2gencfi.c (output_cfi_insn): Scale DW_CFA_advance_loc1,
DW_CFA_advance_loc2 and DW_CFA_advance_loc4 outputs.
2008-11-28 Joshua Kinard <kumba@gentoo.org>
* config/tc-mips.c (hilo_interlocks): Handle CPU_R14000, CPU_R16000.

View file

@ -2159,7 +2159,8 @@ dwarf2dbg.o: dwarf2dbg.c $(INCDIR)/safe-ctype.h dwarf2dbg.h \
dw2gencfi.o: dw2gencfi.c dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
subsegs.h $(INCDIR)/obstack.h
ecoff.o: ecoff.c ecoff.h
ehopt.o: ehopt.c subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h
ehopt.o: ehopt.c subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h \
struc-symbol.h
expr.o: expr.c $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h
flonum-copy.o: flonum-copy.c
flonum-konst.o: flonum-konst.c

View file

@ -3015,7 +3015,8 @@ dwarf2dbg.o: dwarf2dbg.c $(INCDIR)/safe-ctype.h dwarf2dbg.h \
dw2gencfi.o: dw2gencfi.c dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
subsegs.h $(INCDIR)/obstack.h
ecoff.o: ecoff.c ecoff.h
ehopt.o: ehopt.c subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h
ehopt.o: ehopt.c subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h \
struc-symbol.h
expr.o: expr.c $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h
flonum-copy.o: flonum-copy.c
flonum-konst.o: flonum-konst.c

View file

@ -1,5 +1,5 @@
/* dw2gencfi.c - Support for generating Dwarf2 CFI information.
Copyright 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
Copyright 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Michal Ludvig <mludvig@suse.cz>
This file is part of GAS, the GNU Assembler.
@ -972,20 +972,20 @@ output_cfi_insn (struct cfi_insn_data *insn)
if (scaled <= 0x3F)
out_one (DW_CFA_advance_loc + scaled);
else if (delta <= 0xFF)
else if (scaled <= 0xFF)
{
out_one (DW_CFA_advance_loc1);
out_one (delta);
out_one (scaled);
}
else if (delta <= 0xFFFF)
else if (scaled <= 0xFFFF)
{
out_one (DW_CFA_advance_loc2);
out_two (delta);
out_two (scaled);
}
else
{
out_one (DW_CFA_advance_loc4);
out_four (delta);
out_four (scaled);
}
}
else

View file

@ -1,5 +1,6 @@
/* ehopt.c--optimize gcc exception frame information.
Copyright 1998, 2000, 2001, 2003, 2005, 2007 Free Software Foundation, Inc.
Copyright 1998, 2000, 2001, 2003, 2005, 2007, 2008
Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@cygnus.com>.
This file is part of GAS, the GNU Assembler.
@ -21,6 +22,7 @@
#include "as.h"
#include "subsegs.h"
#include "struc-symbol.h"
/* We include this ELF file, even though we may not be assembling for
ELF, since the exception frame information is always in a format
@ -398,13 +400,10 @@ check_eh_frame (expressionS *exp, unsigned int *pnbytes)
subtracted were in the same frag and the expression was
reduced to a constant. We can do the optimization entirely
in this function. */
if (d->cie_info.code_alignment > 0
&& exp->X_add_number % d->cie_info.code_alignment == 0
&& exp->X_add_number / d->cie_info.code_alignment < 0x40)
if (exp->X_add_number < 0x40)
{
d->loc4_frag->fr_literal[d->loc4_fix]
= DW_CFA_advance_loc
| (exp->X_add_number / d->cie_info.code_alignment);
= DW_CFA_advance_loc | exp->X_add_number;
/* No more bytes needed. */
return 1;
}
@ -419,23 +418,39 @@ check_eh_frame (expressionS *exp, unsigned int *pnbytes)
*pnbytes = 2;
}
}
else if (exp->X_op == O_subtract)
else if (exp->X_op == O_subtract && d->cie_info.code_alignment == 1)
{
/* This is a case we can optimize. The expression was not
reduced, so we can not finish the optimization until the end
of the assembly. We set up a variant frag which we handle
later. */
int fr_subtype;
if (d->cie_info.code_alignment > 0)
fr_subtype = d->cie_info.code_alignment << 3;
else
fr_subtype = 0;
frag_var (rs_cfa, 4, 0, fr_subtype, make_expr_symbol (exp),
frag_var (rs_cfa, 4, 0, 1 << 3, make_expr_symbol (exp),
d->loc4_fix, (char *) d->loc4_frag);
return 1;
}
else if ((exp->X_op == O_divide
|| exp->X_op == O_right_shift)
&& d->cie_info.code_alignment > 1)
{
if (exp->X_add_symbol->bsym
&& exp->X_op_symbol->bsym
&& exp->X_add_symbol->sy_value.X_op == O_subtract
&& exp->X_op_symbol->sy_value.X_op == O_constant
&& ((exp->X_op == O_divide
? exp->X_op_symbol->sy_value.X_add_number
: (offsetT) 1 << exp->X_op_symbol->sy_value.X_add_number)
== (offsetT) d->cie_info.code_alignment))
{
/* This is a case we can optimize as well. The expression was
not reduced, so we can not finish the optimization until the
end of the assembly. We set up a variant frag which we
handle later. */
frag_var (rs_cfa, 4, 0, d->cie_info.code_alignment << 3,
make_expr_symbol (&exp->X_add_symbol->sy_value),
d->loc4_fix, (char *) d->loc4_frag);
return 1;
}
}
break;
case state_error:
@ -459,7 +474,9 @@ eh_frame_estimate_size_before_relax (fragS *frag)
diff = resolve_symbol_value (frag->fr_symbol);
if (ca > 0 && diff % ca == 0 && diff / ca < 0x40)
assert (ca > 0);
diff /= ca;
if (diff < 0x40)
ret = 0;
else if (diff < 0x100)
ret = 1;
@ -496,21 +513,21 @@ eh_frame_convert_frag (fragS *frag)
{
offsetT diff;
fragS *loc4_frag;
int loc4_fix;
int loc4_fix, ca;
loc4_frag = (fragS *) frag->fr_opcode;
loc4_fix = (int) frag->fr_offset;
diff = resolve_symbol_value (frag->fr_symbol);
ca = frag->fr_subtype >> 3;
assert (ca > 0);
diff /= ca;
switch (frag->fr_subtype & 7)
{
case 0:
{
int ca = frag->fr_subtype >> 3;
assert (ca > 0 && diff % ca == 0 && diff / ca < 0x40);
loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | (diff / ca);
}
assert (diff < 0x40);
loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | diff;
break;
case 1: