* elf64-ppc.c (ppc64_elf_relocate_section): Correct branch
prediction bits.
This commit is contained in:
parent
070b1dd3c2
commit
86c76c7be0
|
@ -1,3 +1,8 @@
|
||||||
|
2001-11-01 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* elf64-ppc.c (ppc64_elf_relocate_section): Correct branch
|
||||||
|
prediction bits.
|
||||||
|
|
||||||
2001-10-31 Chris Demetriou <cgd@demetriou.com>
|
2001-10-31 Chris Demetriou <cgd@demetriou.com>
|
||||||
|
|
||||||
* elf32-mips.c (_bfd_mips_elf_hi16_reloc): Handle PC-relative
|
* elf32-mips.c (_bfd_mips_elf_hi16_reloc): Handle PC-relative
|
||||||
|
|
|
@ -92,9 +92,6 @@ static boolean ppc64_elf_finish_dynamic_sections
|
||||||
PARAMS ((bfd *, struct bfd_link_info *));
|
PARAMS ((bfd *, struct bfd_link_info *));
|
||||||
|
|
||||||
|
|
||||||
/* Branch prediction bit for branch taken relocs. */
|
|
||||||
#define BRANCH_PREDICT_BIT 0x200000
|
|
||||||
|
|
||||||
/* Mask to set RA in memory instructions. */
|
/* Mask to set RA in memory instructions. */
|
||||||
#define RA_REGISTER_MASK 0x001f0000
|
#define RA_REGISTER_MASK 0x001f0000
|
||||||
|
|
||||||
|
@ -3161,6 +3158,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First handle relocations that tweak non-addend part of insn. */
|
/* First handle relocations that tweak non-addend part of insn. */
|
||||||
|
insn = 0;
|
||||||
switch (r_type)
|
switch (r_type)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
@ -3169,22 +3167,23 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
/* Branch taken prediction relocations. */
|
/* Branch taken prediction relocations. */
|
||||||
case R_PPC64_ADDR14_BRTAKEN:
|
case R_PPC64_ADDR14_BRTAKEN:
|
||||||
case R_PPC64_REL14_BRTAKEN:
|
case R_PPC64_REL14_BRTAKEN:
|
||||||
insn = bfd_get_32 (output_bfd, contents + offset);
|
insn = 0x01 << 21; /* Set 't' bit, lowest bit of BO field. */
|
||||||
if ((relocation - offset) & 0x8000)
|
/* Fall thru. */
|
||||||
insn &= ~BRANCH_PREDICT_BIT;
|
|
||||||
else
|
|
||||||
insn |= BRANCH_PREDICT_BIT;
|
|
||||||
bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Branch not taken predicition relocations. */
|
/* Branch not taken prediction relocations. */
|
||||||
case R_PPC64_ADDR14_BRNTAKEN:
|
case R_PPC64_ADDR14_BRNTAKEN:
|
||||||
case R_PPC64_REL14_BRNTAKEN:
|
case R_PPC64_REL14_BRNTAKEN:
|
||||||
insn = bfd_get_32 (output_bfd, contents + offset);
|
insn |= bfd_get_32 (output_bfd, contents + offset) & ~(0x01 << 21);
|
||||||
if ((relocation - offset) & 0x8000)
|
/* Set 'a' bit. This is 0b00010 in BO field for branch on CR(BI)
|
||||||
insn |= BRANCH_PREDICT_BIT;
|
insns (BO == 001at or 011at), and 0b01000 for branch on CTR
|
||||||
|
insns (BO == 1a00t or 1a01t). */
|
||||||
|
if ((insn & (0x14 << 21)) == (0x04 << 21))
|
||||||
|
insn |= 0x02 << 21;
|
||||||
|
else if ((insn & (0x14 << 21)) == (0x10 << 21))
|
||||||
|
insn |= 0x08 << 21;
|
||||||
else
|
else
|
||||||
insn &= ~BRANCH_PREDICT_BIT;
|
break;
|
||||||
|
|
||||||
bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
|
bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue