aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2002-02-25 03:44:16 +0000
committerAlan Modra <amodra@gmail.com>2002-02-25 03:44:16 +0000
commit96e0dda4c40355ab106f5b2befb6f6f71ed7b39a (patch)
tree51fe8f5bf933c841d62f55069d3d08226cbb0f1f /bfd/elf64-ppc.c
parent94efba1253f92f228fecb86fb0329c41a3721b62 (diff)
downloadgdb-96e0dda4c40355ab106f5b2befb6f6f71ed7b39a.zip
gdb-96e0dda4c40355ab106f5b2befb6f6f71ed7b39a.tar.gz
gdb-96e0dda4c40355ab106f5b2befb6f6f71ed7b39a.tar.bz2
* elf64-ppc.c (ppc64_elf_check_relocs): Warning fix.
(ppc64_elf_relocate_section): Don't generate power4 style branch hints for *_BRTAKEN and *_BRNTAKEN relocs.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r--bfd/elf64-ppc.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index fe46bd5..2e5933a 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -2291,6 +2291,7 @@ ppc64_elf_check_relocs (abfd, info, sec, relocs)
break;
default:
+ break;
}
}
@@ -3631,6 +3632,8 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_vma TOCstart;
boolean ret = true;
boolean is_opd;
+ /* Disabled until we sort out how ld should choose 'y' vs 'at'. */
+ boolean is_power4 = false;
/* Initialize howto table if needed. */
if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
@@ -3760,22 +3763,31 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
/* Branch taken prediction relocations. */
case R_PPC64_ADDR14_BRTAKEN:
case R_PPC64_REL14_BRTAKEN:
- insn = 0x01 << 21; /* Set 't' bit, lowest bit of BO field. */
+ insn = 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field. */
/* Fall thru. */
/* Branch not taken prediction relocations. */
case R_PPC64_ADDR14_BRNTAKEN:
case R_PPC64_REL14_BRNTAKEN:
insn |= bfd_get_32 (output_bfd, contents + offset) & ~(0x01 << 21);
- /* Set 'a' bit. This is 0b00010 in BO field for branch on CR(BI)
- 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;
+ if (is_power4)
+ {
+ /* Set 'a' bit. This is 0b00010 in BO field for branch
+ on CR(BI) 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
+ break;
+ }
else
- break;
+ {
+ /* Invert 'y' bit if not the default. */
+ if ((bfd_signed_vma) (relocation - offset) < 0)
+ insn ^= 0x01 << 21;
+ }
bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
break;