mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-26 04:15:28 +00:00
* config/tc-sh.c (align_test_frag_offset_fixed_p): New.
(sh_optimize_expr): Likewise. * config/tc-sh.h (md_optimize_expr): Define. (sh_optimize_expr): Prototype.
This commit is contained in:
parent
3fcd97f16c
commit
0cc3409506
@ -1,3 +1,10 @@
|
||||
2007-04-14 Kaz Kojima <kkojima@rr.iij4u.or.jp>
|
||||
|
||||
* config/tc-sh.c (align_test_frag_offset_fixed_p): New.
|
||||
(sh_optimize_expr): Likewise.
|
||||
* config/tc-sh.h (md_optimize_expr): Define.
|
||||
(sh_optimize_expr): Prototype.
|
||||
|
||||
2007-04-06 Matt Thomas <matt@netbsd.org>
|
||||
|
||||
* config/tc-vax.c (vax_cons): Added to support %pcrel{8,16,32}(exp)
|
||||
|
@ -825,8 +825,91 @@ sh_elf_cons (register int nbytes)
|
||||
else
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
/* The regular frag_offset_fixed_p doesn't work for rs_align_test
|
||||
frags. */
|
||||
|
||||
static bfd_boolean
|
||||
align_test_frag_offset_fixed_p (const fragS *frag1, const fragS *frag2,
|
||||
bfd_vma *offset)
|
||||
{
|
||||
const fragS *frag;
|
||||
bfd_vma off;
|
||||
|
||||
/* Start with offset initialised to difference between the two frags.
|
||||
Prior to assigning frag addresses this will be zero. */
|
||||
off = frag1->fr_address - frag2->fr_address;
|
||||
if (frag1 == frag2)
|
||||
{
|
||||
*offset = off;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Maybe frag2 is after frag1. */
|
||||
frag = frag1;
|
||||
while (frag->fr_type == rs_align_test)
|
||||
{
|
||||
off += frag->fr_fix;
|
||||
frag = frag->fr_next;
|
||||
if (frag == NULL)
|
||||
break;
|
||||
if (frag == frag2)
|
||||
{
|
||||
*offset = off;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Maybe frag1 is after frag2. */
|
||||
off = frag1->fr_address - frag2->fr_address;
|
||||
frag = frag2;
|
||||
while (frag->fr_type == rs_align_test)
|
||||
{
|
||||
off -= frag->fr_fix;
|
||||
frag = frag->fr_next;
|
||||
if (frag == NULL)
|
||||
break;
|
||||
if (frag == frag1)
|
||||
{
|
||||
*offset = off;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* OBJ_ELF */
|
||||
|
||||
/* Optimize a difference of symbols which have rs_align_test frag if
|
||||
possible. */
|
||||
|
||||
int
|
||||
sh_optimize_expr (expressionS *l, operatorT op, expressionS *r)
|
||||
{
|
||||
#ifdef OBJ_ELF
|
||||
bfd_vma frag_off;
|
||||
|
||||
if (op == O_subtract
|
||||
&& l->X_op == O_symbol
|
||||
&& r->X_op == O_symbol
|
||||
&& S_GET_SEGMENT (l->X_add_symbol) == S_GET_SEGMENT (r->X_add_symbol)
|
||||
&& (SEG_NORMAL (S_GET_SEGMENT (l->X_add_symbol))
|
||||
|| r->X_add_symbol == l->X_add_symbol)
|
||||
&& align_test_frag_offset_fixed_p (symbol_get_frag (l->X_add_symbol),
|
||||
symbol_get_frag (r->X_add_symbol),
|
||||
&frag_off))
|
||||
{
|
||||
l->X_add_number -= r->X_add_number;
|
||||
l->X_add_number -= frag_off / OCTETS_PER_BYTE;
|
||||
l->X_add_number += (S_GET_VALUE (l->X_add_symbol)
|
||||
- S_GET_VALUE (r->X_add_symbol));
|
||||
l->X_op = O_constant;
|
||||
l->X_add_symbol = 0;
|
||||
return 1;
|
||||
}
|
||||
#endif /* OBJ_ELF */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function is called once, at assembler startup time. This should
|
||||
set up all the tables, etc that the MD part of the assembler needs. */
|
||||
|
@ -44,6 +44,12 @@ extern int sh_small;
|
||||
#define md_cons_align(nbytes) sh_cons_align (nbytes)
|
||||
extern void sh_cons_align (int);
|
||||
|
||||
/* We need to optimize expr with taking account of rs_align_test
|
||||
frags. */
|
||||
|
||||
#define md_optimize_expr(l,o,r) sh_optimize_expr (l, o, r)
|
||||
extern int sh_optimize_expr (expressionS *, operatorT, expressionS *);
|
||||
|
||||
/* When relaxing, we need to generate relocations for alignment
|
||||
directives. */
|
||||
#define HANDLE_ALIGN(frag) sh_handle_align (frag)
|
||||
|
Loading…
x
Reference in New Issue
Block a user