2004-01-30 H.J. Lu <hongjiu.lu@intel.com>
* elfxx-ia64.c (elfNN_ia64_relax_brl): New function. (elfNN_ia64_relax_section): Optimize brl to br during the relax finalize pass.
This commit is contained in:
parent
5bbce64e0e
commit
03609792ae
|
@ -1,3 +1,9 @@
|
|||
2004-01-30 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* elfxx-ia64.c (elfNN_ia64_relax_brl): New function.
|
||||
(elfNN_ia64_relax_section): Optimize brl to br during the relax
|
||||
finalize pass.
|
||||
|
||||
2004-01-30 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* elf32-frv.c (elf32_frv_always_size_sections): Initialize pointer
|
||||
|
|
|
@ -672,6 +672,36 @@ bfd_elfNN_ia64_after_parse (int itanium)
|
|||
oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
|
||||
}
|
||||
|
||||
static void
|
||||
elfNN_ia64_relax_brl (bfd *abfd, bfd_byte *contents, bfd_vma off)
|
||||
{
|
||||
int template;
|
||||
bfd_byte *hit_addr;
|
||||
bfd_vma t0, t1, i0, i1, i2;
|
||||
|
||||
hit_addr = (bfd_byte *) (contents + off);
|
||||
hit_addr -= (long) hit_addr & 0x3;
|
||||
t0 = bfd_get_64 (abfd, hit_addr);
|
||||
t1 = bfd_get_64 (abfd, hit_addr + 8);
|
||||
|
||||
/* Keep the instruction in slot 0. */
|
||||
i0 = (t0 >> 5) & 0x1ffffffffffLL;
|
||||
/* Use nop.b for slot 1. */
|
||||
i1 = 0x4000000000LL;
|
||||
/* For slot 2, turn brl into br by masking out bit 40. */
|
||||
i2 = (t1 >> 23) & 0x0ffffffffffLL;
|
||||
|
||||
/* Turn a MLX bundle into a MBB bundle with the same stop-bit
|
||||
variety. */
|
||||
template = 0x12;
|
||||
if ((t0 & 0x1fLL) == 5)
|
||||
template += 1;
|
||||
t0 = (i1 << 46) | (i0 << 5) | template;
|
||||
t1 = (i2 << 23) | (i1 >> 18);
|
||||
|
||||
bfd_put_64 (abfd, t0, hit_addr);
|
||||
bfd_put_64 (abfd, t1, hit_addr + 8);
|
||||
}
|
||||
|
||||
/* These functions do relaxation for IA-64 ELF. */
|
||||
|
||||
|
@ -765,13 +795,30 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
|
|||
case R_IA64_PCREL21BI:
|
||||
case R_IA64_PCREL21M:
|
||||
case R_IA64_PCREL21F:
|
||||
/* In the finalize pass, all br relaxations are done. We can
|
||||
skip it. */
|
||||
if (!link_info->need_relax_finalize)
|
||||
continue;
|
||||
is_branch = TRUE;
|
||||
break;
|
||||
|
||||
case R_IA64_PCREL60B:
|
||||
/* We can't optimize brl to br before the finalize pass since
|
||||
br relaxations will increase the code size. Defer it to
|
||||
the finalize pass. */
|
||||
if (link_info->need_relax_finalize)
|
||||
{
|
||||
sec->need_finalize_relax = 1;
|
||||
continue;
|
||||
}
|
||||
is_branch = TRUE;
|
||||
break;
|
||||
|
||||
case R_IA64_LTOFF22X:
|
||||
case R_IA64_LDXMOV:
|
||||
/* We can't relax ldx/mov before the finalize pass since
|
||||
br relaxations will increase the code size. Defer it to
|
||||
the finalize pass. */
|
||||
if (link_info->need_relax_finalize)
|
||||
{
|
||||
sec->need_finalize_relax = 1;
|
||||
|
@ -885,6 +932,25 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
|
|||
/* If the branch is in range, no need to do anything. */
|
||||
if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
|
||||
&& (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
|
||||
{
|
||||
/* If the 60-bit branch is in 21-bit range, optimize it. */
|
||||
if (r_type == R_IA64_PCREL60B)
|
||||
{
|
||||
elfNN_ia64_relax_brl (abfd, contents, roff);
|
||||
|
||||
irel->r_info
|
||||
= ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
|
||||
R_IA64_PCREL21B);
|
||||
|
||||
/* If the original relocation offset points to slot
|
||||
1, change it to slot 2. */
|
||||
if ((irel->r_offset & 3) == 1)
|
||||
irel->r_offset += 1;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (r_type == R_IA64_PCREL60B)
|
||||
continue;
|
||||
|
||||
/* If the branch and target are in the same section, you've
|
||||
|
|
Loading…
Reference in New Issue