diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d755313e72..4dc7bf3559 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2002-02-25 Alan Modra + + * 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. + 2002-02-22 Jakub Jelinek * elf64-sh64.c (sh_elf64_relocate_section): Fix a typo from my diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index fe46bd53ea..2e5933a7e1 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;