* 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:
parent
3aa3176b2d
commit
395e834521
5 changed files with 66 additions and 30 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
61
gas/ehopt.c
61
gas/ehopt.c
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue