/* Whether to use user friendly register names. */
#ifndef TARGET_REG_NAMES_P
#ifdef TE_PE
-#define TARGET_REG_NAMES_P true
+#define TARGET_REG_NAMES_P TRUE
#else
-#define TARGET_REG_NAMES_P false
+#define TARGET_REG_NAMES_P FALSE
#endif
#endif
#define PPC_HA(v) PPC_HI ((v) + 0x8000)
/* #higher(value) denotes bits 32 through 47 of the indicated value. */
-#define PPC_HIGHER(v) (((v) >> 32) & 0xffff)
+#define PPC_HIGHER(v) (((v) >> 16 >> 16) & 0xffff)
/* #highera(value) denotes bits 32 through 47 of the indicated value,
compensating for #lo() being treated as a signed number. */
#define PPC_HIGHERA(v) PPC_HIGHER ((v) + 0x8000)
/* #highest(value) denotes bits 48 through 63 of the indicated value. */
-#define PPC_HIGHEST(v) (((v) >> 48) & 0xffff)
+#define PPC_HIGHEST(v) (((v) >> 24 >> 24) & 0xffff)
/* #highesta(value) denotes bits 48 through 63 of the indicated value,
compensating for #lo being treated as a signed number. */
#define SEX16(val) ((((val) & 0xffff) ^ 0x8000) - 0x8000)
-static boolean reg_names_p = TARGET_REG_NAMES_P;
+static bfd_boolean reg_names_p = TARGET_REG_NAMES_P;
-static boolean register_name PARAMS ((expressionS *));
+static bfd_boolean register_name PARAMS ((expressionS *));
static void ppc_set_cpu PARAMS ((void));
static unsigned long ppc_insert_operand
PARAMS ((unsigned long insn, const struct powerpc_operand *operand,
static void ppc_elf_rdata PARAMS ((int));
static void ppc_elf_lcomm PARAMS ((int));
static void ppc_elf_validate_fix PARAMS ((fixS *, segT));
+static void ppc_apuinfo_section_add PARAMS ((unsigned int apu, unsigned int version));
#endif
#ifdef TE_PE
{ "rdata", ppc_elf_rdata, 0 },
{ "rodata", ppc_elf_rdata, 0 },
{ "lcomm", ppc_elf_lcomm, 0 },
- { "file", dwarf2_directive_file, 0 },
+ { "file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
{ "loc", dwarf2_directive_loc, 0 },
#endif
* original state.
*/
-static boolean
+static bfd_boolean
register_name (expressionP)
expressionS *expressionP;
{
name = ++input_line_pointer;
else if (!reg_names_p || !ISALPHA (name[0]))
- return false;
+ return FALSE;
c = get_symbol_end ();
reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name);
/* Make the rest nice. */
expressionP->X_add_symbol = NULL;
expressionP->X_op_symbol = NULL;
- return true;
+ return TRUE;
}
/* Reset the line as if we had not done anything. */
input_line_pointer = start;
- return false;
+ return FALSE;
}
\f
/* This function is called for each symbol seen in an expression. It
to use for condition codes. */
/* Whether to do the special parsing. */
-static boolean cr_operand;
+static bfd_boolean cr_operand;
/* Names to recognize in a condition code. This table is sorted. */
static const struct pd_reg cr_names[] =
/* The type of processor we are assembling for. This is one or more
of the PPC_OPCODE flags defined in opcode/ppc.h. */
-static int ppc_cpu = 0;
+static unsigned long ppc_cpu = 0;
-/* The size of the processor we are assembling for. This is either
- PPC_OPCODE_32 or PPC_OPCODE_64. */
-static unsigned long ppc_size = (BFD_DEFAULT_TARGET_SIZE == 64
- ? PPC_OPCODE_64
- : PPC_OPCODE_32);
-
-/* Whether to target xcoff64. */
-static int ppc_xcoff64 = 0;
+/* Whether to target xcoff64/elf64. */
+static unsigned int ppc_obj64 = BFD_DEFAULT_TARGET_SIZE == 64;
/* Opcode hash table. */
static struct hash_control *ppc_hash;
/* Whether this is Solaris or not. */
#ifdef TARGET_SOLARIS_COMMENT
-#define SOLARIS_P true
+#define SOLARIS_P TRUE
#else
-#define SOLARIS_P false
+#define SOLARIS_P FALSE
#endif
-static boolean msolaris = SOLARIS_P;
+static bfd_boolean msolaris = SOLARIS_P;
#endif
#ifdef OBJ_XCOFF
#ifdef OBJ_ELF
symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE" */
+#define PPC_APUINFO_ISEL 0x40
+#define PPC_APUINFO_PMR 0x41
+#define PPC_APUINFO_RFMCI 0x42
+#define PPC_APUINFO_CACHELCK 0x43
+#define PPC_APUINFO_SPE 0x100
+#define PPC_APUINFO_EFS 0x101
+#define PPC_APUINFO_BRLOCK 0x102
+
+/*
+ * We keep a list of APUinfo
+ */
+unsigned long *ppc_apuinfo_list;
+unsigned int ppc_apuinfo_num;
+unsigned int ppc_apuinfo_num_alloc;
#endif /* OBJ_ELF */
\f
#ifdef OBJ_ELF
/* a64 and a32 determine whether to use XCOFF64 or XCOFF32. */
case 'a':
if (strcmp (arg, "64") == 0)
- ppc_xcoff64 = 1;
+ {
+#ifdef BFD64
+ ppc_obj64 = 1;
+#else
+ as_fatal (_("%s unsupported"), "-a64");
+#endif
+ }
else if (strcmp (arg, "32") == 0)
- ppc_xcoff64 = 0;
+ ppc_obj64 = 0;
else
return 0;
break;
case 'm':
- /* Most CPU's are 32 bit. Exceptions are listed below. */
- ppc_size = PPC_OPCODE_32;
-
/* -mpwrx and -mpwr2 mean to assemble for the IBM POWER/2
(RIOS2). */
if (strcmp (arg, "pwrx") == 0 || strcmp (arg, "pwr2") == 0)
- ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_POWER2;
+ ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_32;
/* -mpwr means to assemble for the IBM POWER (RIOS1). */
else if (strcmp (arg, "pwr") == 0)
- ppc_cpu = PPC_OPCODE_POWER;
+ ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_32;
/* -m601 means to assemble for the PowerPC 601, which includes
instructions that are holdovers from the Power. */
else if (strcmp (arg, "601") == 0)
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_601;
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_601 | PPC_OPCODE_32);
/* -mppc, -mppc32, -m603, and -m604 mean to assemble for the
PowerPC 603/604. */
else if (strcmp (arg, "ppc") == 0
|| strcmp (arg, "ppc32") == 0
|| strcmp (arg, "603") == 0
|| strcmp (arg, "604") == 0)
- ppc_cpu = PPC_OPCODE_PPC;
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
/* -m403 and -m405 mean to assemble for the PowerPC 403/405. */
else if (strcmp (arg, "403") == 0
- || strcmp (arg, "405") == 0)
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_403;
+ || strcmp (arg, "405") == 0)
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_403 | PPC_OPCODE_32);
else if (strcmp (arg, "7400") == 0
- || strcmp (arg, "7410") == 0
- || strcmp (arg, "7450") == 0
- || strcmp (arg, "7455") == 0)
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC;
+ || strcmp (arg, "7410") == 0
+ || strcmp (arg, "7450") == 0
+ || strcmp (arg, "7455") == 0)
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_ALTIVEC | PPC_OPCODE_32);
else if (strcmp (arg, "altivec") == 0)
- {
- if (ppc_cpu == 0)
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC;
- else
- ppc_cpu |= PPC_OPCODE_ALTIVEC;
- }
+ {
+ if (ppc_cpu == 0)
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC;
+ else
+ ppc_cpu |= PPC_OPCODE_ALTIVEC;
+ }
+ else if (strcmp (arg, "e500") == 0 || strcmp (arg, "e500x2") == 0)
+ {
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
+ | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
+ | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
+ | PPC_OPCODE_RFMCI);
+ }
+ else if (strcmp (arg, "spe") == 0)
+ {
+ if (ppc_cpu == 0)
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_SPE | PPC_OPCODE_EFS;
+ else
+ ppc_cpu |= PPC_OPCODE_SPE;
+ }
/* -mppc64 and -m620 mean to assemble for the 64-bit PowerPC
620. */
else if (strcmp (arg, "ppc64") == 0 || strcmp (arg, "620") == 0)
{
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64;
- ppc_size = PPC_OPCODE_64;
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
}
else if (strcmp (arg, "ppc64bridge") == 0)
{
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE | PPC_OPCODE_64;
- ppc_size = PPC_OPCODE_64;
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_64_BRIDGE | PPC_OPCODE_64);
}
/* -mbooke/-mbooke32 mean enable 32-bit BookE support. */
else if (strcmp (arg, "booke") == 0 || strcmp (arg, "booke32") == 0)
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_BOOKE;
+ {
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32;
+ }
/* -mbooke64 means enable 64-bit BookE support. */
else if (strcmp (arg, "booke64") == 0)
{
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_BOOKE |
- PPC_OPCODE_BOOKE64 | PPC_OPCODE_64;
- ppc_size = PPC_OPCODE_64;
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE
+ | PPC_OPCODE_BOOKE64 | PPC_OPCODE_64);
}
else if (strcmp (arg, "power4") == 0)
{
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4;
- ppc_size = PPC_OPCODE_64;
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_64 | PPC_OPCODE_POWER4);
}
/* -mcom means assemble for the common intersection between Power
and PowerPC. At present, we just allow the union, rather
than the intersection. */
else if (strcmp (arg, "com") == 0)
- ppc_cpu = PPC_OPCODE_COMMON;
+ ppc_cpu = PPC_OPCODE_COMMON | PPC_OPCODE_32;
/* -many means to assemble for any architecture (PWR/PWRX/PPC). */
else if (strcmp (arg, "any") == 0)
- ppc_cpu = PPC_OPCODE_ANY;
+ ppc_cpu = PPC_OPCODE_ANY | PPC_OPCODE_32;
else if (strcmp (arg, "regnames") == 0)
- reg_names_p = true;
+ reg_names_p = TRUE;
else if (strcmp (arg, "no-regnames") == 0)
- reg_names_p = false;
+ reg_names_p = FALSE;
#ifdef OBJ_ELF
/* -mrelocatable/-mrelocatable-lib -- warn about initializations
else if (strcmp (arg, "solaris") == 0)
{
- msolaris = true;
+ msolaris = TRUE;
ppc_comment_chars = ppc_solaris_comment_chars;
}
else if (strcmp (arg, "no-solaris") == 0)
{
- msolaris = false;
+ msolaris = FALSE;
ppc_comment_chars = ppc_eabi_comment_chars;
}
#endif
-many generate code for any architecture (PWR/PWRX/PPC)\n\
-mregnames Allow symbolic names for registers\n\
-mno-regnames Do not allow symbolic names for registers\n"));
+ fprintf (stream, _("\
+-me500, -me500x2 generate code for Motorola e500 core complex\n\
+-mspe generate code for Motorola SPE instructions\n"));
#ifdef OBJ_ELF
fprintf (stream, _("\
-mrelocatable support for GCC's -mrelocatble option\n\
if (ppc_cpu == 0)
{
- if (strncmp (default_os, "aix", 3) == 0
- && default_os[3] >= '4' && default_os[3] <= '9')
- ppc_cpu = PPC_OPCODE_COMMON;
+ if (ppc_obj64)
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
+ else if (strncmp (default_os, "aix", 3) == 0
+ && default_os[3] >= '4' && default_os[3] <= '9')
+ ppc_cpu = PPC_OPCODE_COMMON | PPC_OPCODE_32;
else if (strncmp (default_os, "aix3", 4) == 0)
- ppc_cpu = PPC_OPCODE_POWER;
+ ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_32;
else if (strcmp (default_cpu, "rs6000") == 0)
- ppc_cpu = PPC_OPCODE_POWER;
+ ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_32;
else if (strncmp (default_cpu, "powerpc", 7) == 0)
- ppc_cpu = PPC_OPCODE_PPC;
+ {
+ if (default_cpu[7] == '6' && default_cpu[8] == '4')
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
+ else
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
+ }
else
as_fatal (_("Unknown default cpu = %s, os = %s"),
default_cpu, default_os);
unsigned long
ppc_mach ()
{
- return ppc_size == PPC_OPCODE_64 ? 620 : 0;
-}
-
-#ifdef OBJ_XCOFF
-int
-ppc_subseg_align ()
-{
- return ppc_xcoff64 ? 3 : 2;
+ if (ppc_obj64)
+ return bfd_mach_ppc64;
+ else if (ppc_arch () == bfd_arch_rs6000)
+ return bfd_mach_rs6k;
+ else
+ return bfd_mach_ppc;
}
-#endif
extern char*
ppc_target_format ()
return "xcoff-powermac";
#else
# ifdef TE_AIX5
- return (ppc_xcoff64 ? "aix5coff64-rs6000" : "aixcoff-rs6000");
+ return (ppc_obj64 ? "aix5coff64-rs6000" : "aixcoff-rs6000");
# else
- return (ppc_xcoff64 ? "aixcoff64-rs6000" : "aixcoff-rs6000");
+ return (ppc_obj64 ? "aixcoff64-rs6000" : "aixcoff-rs6000");
# endif
#endif
#endif
#ifdef OBJ_ELF
- boolean is64 = BFD_DEFAULT_TARGET_SIZE == 64 && ppc_size == PPC_OPCODE_64;
-
return (target_big_endian
- ? (is64 ? "elf64-powerpc" : "elf32-powerpc")
- : (is64 ? "elf64-powerpcle" : "elf32-powerpcle"));
+ ? (ppc_obj64 ? "elf64-powerpc" : "elf32-powerpc")
+ : (ppc_obj64 ? "elf64-powerpcle" : "elf32-powerpcle"));
#endif
}
const struct powerpc_opcode *op_end;
const struct powerpc_macro *macro;
const struct powerpc_macro *macro_end;
- boolean dup_insn = false;
+ bfd_boolean dup_insn = FALSE;
ppc_set_cpu ();
{
know ((op->opcode & op->mask) == op->opcode);
- if ((op->flags & ppc_cpu) != 0
+ if ((op->flags & ppc_cpu & ~(PPC_OPCODE_32 | PPC_OPCODE_64)) != 0
&& ((op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64)) == 0
- || (op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64)) == ppc_size
+ || ((op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64))
+ == (ppc_cpu & (PPC_OPCODE_32 | PPC_OPCODE_64)))
|| (ppc_cpu & PPC_OPCODE_64_BRIDGE) != 0)
+ /* Certain instructions (eg: extsw) do not exist in the
+ 32-bit BookE instruction set, but they do exist in the
+ 64-bit BookE instruction set, and other PPC instruction
+ sets. Check to see if the opcode has the BOOKE64 flag set.
+ If it does make sure that the target CPU is not the BookE32. */
+ && ((op->flags & PPC_OPCODE_BOOKE64) == 0
+ || (ppc_cpu & PPC_OPCODE_BOOKE64) == PPC_OPCODE_BOOKE64
+ || (ppc_cpu & PPC_OPCODE_BOOKE) == 0)
&& ((op->flags & (PPC_OPCODE_POWER4 | PPC_OPCODE_NOPOWER4)) == 0
|| ((op->flags & PPC_OPCODE_POWER4)
== (ppc_cpu & PPC_OPCODE_POWER4))))
as_bad (_("Internal assembler error for instruction %s"),
op->name);
- dup_insn = true;
+ dup_insn = TRUE;
}
}
}
if (retval != (const char *) NULL)
{
as_bad (_("Internal assembler error for macro %s"), macro->name);
- dup_insn = true;
+ dup_insn = TRUE;
}
}
}
#endif
}
+void
+ppc_cleanup ()
+{
+#ifdef OBJ_ELF
+ if (ppc_apuinfo_list == NULL)
+ return;
+
+ /* Ok, so write the section info out. We have this layout:
+
+ byte data what
+ ---- ---- ----
+ 0 8 length of "APUinfo\0"
+ 4 (n*4) number of APU's (4 bytes each)
+ 8 2 note type 2
+ 12 "APUinfo\0" name
+ 20 APU#1 first APU's info
+ 24 APU#2 second APU's info
+ ... ...
+ */
+ {
+ char *p;
+ asection *seg = now_seg;
+ subsegT subseg = now_subseg;
+ asection *apuinfo_secp = (asection *) NULL;
+ unsigned int i;
+
+ /* Create the .PPC.EMB.apuinfo section. */
+ apuinfo_secp = subseg_new (".PPC.EMB.apuinfo", 0);
+ bfd_set_section_flags (stdoutput,
+ apuinfo_secp,
+ SEC_HAS_CONTENTS | SEC_READONLY);
+
+ p = frag_more (4);
+ md_number_to_chars (p, (valueT) 8, 4);
+
+ p = frag_more (4);
+ md_number_to_chars (p, (valueT) ppc_apuinfo_num, 4);
+
+ p = frag_more (4);
+ md_number_to_chars (p, (valueT) 2, 4);
+
+ p = frag_more (8);
+ strcpy (p, "APUinfo");
+
+ for (i = 0; i < ppc_apuinfo_num; i++)
+ {
+ p = frag_more (4);
+ md_number_to_chars (p, (valueT) ppc_apuinfo_list[i], 4);
+ }
+
+ frag_align (2, 0, 0);
+
+ /* We probably can't restore the current segment, for there likely
+ isn't one yet... */
+ if (seg && subseg)
+ subseg_set (seg, subseg);
+ }
+#endif
+}
+
/* Insert an operand value into an instruction. */
static unsigned long
max = (1 << (operand->bits - 1)) - 1;
min = - (1 << (operand->bits - 1));
- if (ppc_size == PPC_OPCODE_32)
+ if (!ppc_obj64)
{
/* Some people write 32 bit hex constants with the sign
extension done by hand. This shouldn't really be
const char *errmsg;
errmsg = NULL;
- insn = (*operand->insert) (insn, (long) val, ppc_cpu | ppc_size, &errmsg);
+ insn = (*operand->insert) (insn, (long) val, ppc_cpu, &errmsg);
if (errmsg != (const char *) NULL)
as_bad_where (file, line, errmsg);
}
MAP ("bitfld", (int) BFD_RELOC_PPC_EMB_BIT_FLD),
MAP ("relsda", (int) BFD_RELOC_PPC_EMB_RELSDA),
MAP ("xgot", (int) BFD_RELOC_PPC_TOC16),
-#if BFD_DEFAULT_TARGET_SIZE == 64
+ /* The following are only valid for ppc64. Negative values are
+ used instead of a flag. */
MAP ("higher", - (int) BFD_RELOC_PPC64_HIGHER),
MAP ("highera", - (int) BFD_RELOC_PPC64_HIGHER_S),
MAP ("highest", - (int) BFD_RELOC_PPC64_HIGHEST),
MAP ("toc@l", - (int) BFD_RELOC_PPC64_TOC16_LO),
MAP ("toc@h", - (int) BFD_RELOC_PPC64_TOC16_HI),
MAP ("toc@ha", - (int) BFD_RELOC_PPC64_TOC16_HA),
-#endif
{ (char *) 0, 0, (int) BFD_RELOC_UNUSED }
};
{
int reloc = ptr->reloc;
- if (BFD_DEFAULT_TARGET_SIZE == 64 && reloc < 0)
+ if (reloc < 0)
{
- if (ppc_size != PPC_OPCODE_64)
+ if (!ppc_obj64)
return BFD_RELOC_UNUSED;
reloc = -reloc;
}
}
*str_p = str;
- if (BFD_DEFAULT_TARGET_SIZE == 64
- && reloc == (int) BFD_RELOC_PPC64_TOC
+ if (reloc == (int) BFD_RELOC_PPC64_TOC
&& exp_p->X_op == O_symbol)
{
/* This reloc type ignores the symbol. Change the symbol
}
}
-#if BFD_DEFAULT_TARGET_SIZE == 64
-/* Don't emit .TOC. symbol. */
-int
-ppc_elf_frob_symbol (sym)
- symbolS *sym;
+/* Prevent elf_frob_file_before_adjust removing a weak undefined
+ function descriptor sym if the corresponding code sym is used. */
+
+void
+ppc_frob_file_before_adjust ()
{
- const char *name;
+ symbolS *symp;
+
+ if (!ppc_obj64)
+ return;
- name = S_GET_NAME (sym);
- if (name != NULL && strcmp (name, ".TOC.") == 0)
+ for (symp = symbol_rootP; symp; symp = symbol_next (symp))
{
- S_CLEAR_EXTERNAL (sym);
- return 1;
+ const char *name;
+ char *dotname;
+ symbolS *dotsym;
+ size_t len;
+
+ name = S_GET_NAME (symp);
+ if (name[0] == '.')
+ continue;
+
+ if (! S_IS_WEAK (symp)
+ || S_IS_DEFINED (symp))
+ continue;
+
+ len = strlen (name) + 1;
+ dotname = xmalloc (len + 1);
+ dotname[0] = '.';
+ memcpy (dotname + 1, name, len);
+ dotsym = symbol_find (dotname);
+ free (dotname);
+ if (dotsym != NULL && (symbol_used_p (dotsym)
+ || symbol_used_in_reloc_p (dotsym)))
+ {
+ symbol_mark_used (symp);
+ }
}
- return 0;
+ /* Don't emit .TOC. symbol. */
+ symp = symbol_find (".TOC.");
+ if (symp != NULL)
+ symbol_remove (symp, &symbol_rootP, &symbol_lastP);
}
-#endif
#endif /* OBJ_ELF */
\f
#ifdef TE_PE
#endif
\f
+#ifdef OBJ_ELF
+#define APUID(a,v) ((((a) & 0xffff) << 16) | ((v) & 0xffff))
+static void
+ppc_apuinfo_section_add (apu, version)
+ unsigned int apu, version;
+{
+ unsigned int i;
+
+ /* Check we don't already exist. */
+ for (i = 0; i < ppc_apuinfo_num; i++)
+ if (ppc_apuinfo_list[i] == APUID (apu, version))
+ return;
+
+ if (ppc_apuinfo_num == ppc_apuinfo_num_alloc)
+ {
+ if (ppc_apuinfo_num_alloc == 0)
+ {
+ ppc_apuinfo_num_alloc = 4;
+ ppc_apuinfo_list = (unsigned long *)
+ xmalloc (sizeof (unsigned long) * ppc_apuinfo_num_alloc);
+ }
+ else
+ {
+ ppc_apuinfo_num_alloc += 4;
+ ppc_apuinfo_list = (unsigned long *) xrealloc (ppc_apuinfo_list,
+ sizeof (unsigned long) * ppc_apuinfo_num_alloc);
+ }
+ }
+ ppc_apuinfo_list[ppc_apuinfo_num++] = APUID (apu, version);
+}
+#undef APUID
+#endif
+\f
+
/* We need to keep a list of fixups. We can't simply generate them as
we go, because that would require us to first create the frag, and
that would screw up references to ``.''. */
if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
{
unsigned int opcount;
+ unsigned int num_operands_expected;
+ unsigned int i;
/* There is an optional operand. Count the number of
commas in the input line. */
}
}
+ /* Compute the number of expected operands.
+ Do not count fake operands. */
+ for (num_operands_expected = 0, i = 0; opcode->operands[i]; i ++)
+ if ((powerpc_operands [opcode->operands[i]].flags & PPC_OPERAND_FAKE) == 0)
+ ++ num_operands_expected;
+
/* If there are fewer operands in the line then are called
for by the instruction, we want to skip the optional
operand. */
- if (opcount < strlen (opcode->operands))
+ if (opcount < num_operands_expected)
skip_optional = 1;
break;
operand = &powerpc_operands[next_opindex];
next_opindex = 0;
}
-
errmsg = NULL;
/* If this is a fake operand, then we do not expect anything
from the input. */
if ((operand->flags & PPC_OPERAND_FAKE) != 0)
{
- insn = (*operand->insert) (insn, 0L, ppc_cpu | ppc_size, &errmsg);
+ insn = (*operand->insert) (insn, 0L, ppc_cpu, &errmsg);
if (errmsg != (const char *) NULL)
as_bad (errmsg);
continue;
{
if (operand->insert)
{
- insn = (*operand->insert) (insn, 0L, ppc_cpu | ppc_size, &errmsg);
+ insn = (*operand->insert) (insn, 0L, ppc_cpu, &errmsg);
if (errmsg != (const char *) NULL)
as_bad (errmsg);
}
if (! register_name (&ex))
{
if ((operand->flags & PPC_OPERAND_CR) != 0)
- cr_operand = true;
+ cr_operand = TRUE;
expression (&ex);
- cr_operand = false;
+ cr_operand = FALSE;
}
}
ex.X_add_number = SEX16 (PPC_HA (ex.X_add_number));
break;
-#if BFD_DEFAULT_TARGET_SIZE == 64
case BFD_RELOC_PPC64_HIGHER:
if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
ex.X_add_number = PPC_HIGHER (ex.X_add_number);
else
ex.X_add_number = SEX16 (PPC_HIGHESTA (ex.X_add_number));
break;
-#endif /* BFD_DEFAULT_TARGET_SIZE == 64 */
}
#endif /* OBJ_ELF */
insn = ppc_insert_operand (insn, operand, ex.X_add_number,
}
}
- if (BFD_DEFAULT_TARGET_SIZE == 64
- && ppc_size == PPC_OPCODE_64
+ if (ppc_obj64
&& (operand->flags & PPC_OPERAND_DS) != 0)
{
switch (reloc)
if (*str != '\0')
as_bad (_("junk at end of line: `%s'"), str);
+#ifdef OBJ_ELF
+ /* Do we need/want a APUinfo section? */
+ if (ppc_cpu & (PPC_OPCODE_SPE
+ | PPC_OPCODE_ISEL | PPC_OPCODE_EFS
+ | PPC_OPCODE_BRLOCK | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
+ | PPC_OPCODE_RFMCI))
+ {
+ /* These are all version "1". */
+ if (opcode->flags & PPC_OPCODE_SPE)
+ ppc_apuinfo_section_add (PPC_APUINFO_SPE, 1);
+ if (opcode->flags & PPC_OPCODE_ISEL)
+ ppc_apuinfo_section_add (PPC_APUINFO_ISEL, 1);
+ if (opcode->flags & PPC_OPCODE_EFS)
+ ppc_apuinfo_section_add (PPC_APUINFO_EFS, 1);
+ if (opcode->flags & PPC_OPCODE_BRLOCK)
+ ppc_apuinfo_section_add (PPC_APUINFO_BRLOCK, 1);
+ if (opcode->flags & PPC_OPCODE_PMR)
+ ppc_apuinfo_section_add (PPC_APUINFO_PMR, 1);
+ if (opcode->flags & PPC_OPCODE_CACHELCK)
+ ppc_apuinfo_section_add (PPC_APUINFO_CACHELCK, 1);
+ if (opcode->flags & PPC_OPCODE_RFMCI)
+ ppc_apuinfo_section_add (PPC_APUINFO_RFMCI, 1);
+ }
+#endif
+
/* Write out the instruction. */
f = frag_more (4);
md_number_to_chars (f, insn, 4);
case BFD_RELOC_HI16:
case BFD_RELOC_HI16_S:
#ifdef OBJ_ELF
-#if BFD_DEFAULT_TARGET_SIZE == 64
case BFD_RELOC_PPC64_HIGHER:
case BFD_RELOC_PPC64_HIGHER_S:
case BFD_RELOC_PPC64_HIGHEST:
case BFD_RELOC_PPC64_HIGHEST_S:
-#endif
#endif
fixP->fx_no_overflow = 1;
break;
if (letter == 'e')
return SHF_EXCLUDE;
- *ptr_msg = _("Bad .section directive: want a,e,w,x,M,S in string");
+ *ptr_msg = _("Bad .section directive: want a,e,w,x,M,S,G,T in string");
return 0;
}
/* This is set if we are creating a .stabx symbol, since we don't want
to handle symbol suffixes for such symbols. */
-static boolean ppc_stab_symbol;
+static bfd_boolean ppc_stab_symbol;
/* The .comm and .lcomm pseudo-ops for XCOFF. XCOFF puts common
symbols in the .bss segment as though they were local common
symbol_set_frag (sym, frag_now);
S_SET_VALUE (sym, (valueT) frag_now_fix ());
- symbol_get_tc (sym)->align = (ppc_xcoff64) ? 3 : 2;
+ symbol_get_tc (sym)->align = 2;
symbol_get_tc (sym)->output = 1;
symbol_get_tc (sym)->within = sym;
}
++input_line_pointer;
- ppc_stab_symbol = true;
+ ppc_stab_symbol = TRUE;
sym = symbol_make (name);
- ppc_stab_symbol = false;
+ ppc_stab_symbol = FALSE;
symbol_get_tc (sym)->real_name = name;
++input_line_pointer;
/* Align to a four/eight byte boundary. */
- align = BFD_DEFAULT_TARGET_SIZE == 64 && ppc_size == PPC_OPCODE_64 ? 3 : 2;
+ align = ppc_obj64 ? 3 : 2;
frag_align (align, 0, 0);
record_alignment (now_seg, align);
#endif /* OBJ_ELF */
else
{
++input_line_pointer;
- cons ((ppc_size == PPC_OPCODE_64) ? 8 : 4);
+ cons (ppc_obj64 ? 8 : 4);
}
}
/* Pseudo-op .machine. */
/* FIXME: `.machine' is a nop for the moment. It would be nice to
- accept this directive on the first line of input and set ppc_size
+ accept this directive on the first line of input and set ppc_obj64
and the target format accordingly. Unfortunately, the target
format is selected in output-file.c:output_file_create before we
even get to md_begin, so it's not possible without changing
#endif
#ifdef OBJ_ELF
const char *sname = segment_name (S_GET_SEGMENT (sym));
- if (BFD_DEFAULT_TARGET_SIZE == 64 && ppc_size == PPC_OPCODE_64)
+ if (ppc_obj64)
return strcmp (sname, ".toc") == 0;
else
return strcmp (sname, ".got") == 0;
/* pseudo-op: .pdata
behaviour: predefined read only data section
- double word aligned
+ double word aligned
errors: None
warnings: None
initial: .section .pdata "adr3"
- a - don't know -- maybe a misprint
+ a - don't know -- maybe a misprint
d - initialized data
r - readable
3 - double word aligned (that would be 4 byte boundary)
/* pseudo-op: .ydata
behaviour: predefined read only data section
- double word aligned
+ double word aligned
errors: None
warnings: None
initial: .section .ydata "drw3"
- a - don't know -- maybe a misprint
+ a - don't know -- maybe a misprint
d - initialized data
r - readable
3 - double word aligned (that would be 4 byte boundary)
/* pseudo-op: .reldata
behaviour: predefined read write data section
- double word aligned (4-byte)
+ double word aligned (4-byte)
FIXME: relocation is applied to it
FIXME: what's the difference between this and .data?
errors: None
/* pseudo-op: .rdata
behaviour: predefined read only data section
- double word aligned
+ double word aligned
errors: None
warnings: None
initial: .section .rdata "dr3"
/* pseudo-op: .ualong
behaviour: much like .int, with the exception that no alignment is
- performed.
+ performed.
FIXME: test the alignment statement
errors: None
warnings: None */
/* pseudo-op: .znop <symbol name>
behaviour: Issue a nop instruction
- Issue a IMAGE_REL_PPC_IFGLUE relocation against it, using
+ Issue a IMAGE_REL_PPC_IFGLUE relocation against it, using
the supplied symbol name.
errors: None
warnings: Missing symbol name */
seen. It tells ppc_adjust_symtab whether it needs to look through
the symbols. */
-static boolean ppc_saw_abs;
+static bfd_boolean ppc_saw_abs;
/* Change the name of a symbol just before writing it out. Set the
real name if the .rename pseudo-op was used. Otherwise, remove any
&& S_GET_STORAGE_CLASS (sym) != C_FILE)))
return 1;
+ /* This one will disappear anyway. Don't make a csect sym for it. */
+ if (sym == abs_section_sym)
+ return 1;
+
if (symbol_get_tc (sym)->real_name != (char *) NULL)
S_SET_NAME (sym, symbol_get_tc (sym)->real_name);
else
{
/* This is an absolute symbol. The csect will be created by
ppc_adjust_symtab. */
- ppc_saw_abs = true;
+ ppc_saw_abs = TRUE;
a->x_csect.x_smtyp = XTY_LD;
if (symbol_get_tc (sym)->class == -1)
symbol_get_tc (sym)->class = XMC_XO;
/* We want the value to be the symbol index of the referenced
csect symbol. BFD will do that for us if we set the right
flags. */
- S_SET_VALUE (sym,
- ((valueT)
- coffsymbol (symbol_get_bfdsym
- (symbol_get_tc (sym)->within))->native));
+ asymbol *bsym = symbol_get_bfdsym (symbol_get_tc (sym)->within);
+ combined_entry_type *c = coffsymbol (bsym)->native;
+
+ S_SET_VALUE (sym, (valueT) (size_t) c);
coffsymbol (symbol_get_bfdsym (sym))->native->fix_value = 1;
}
else if (S_GET_STORAGE_CLASS (sym) == C_STSYM)
coffsymbol (symbol_get_bfdsym (sym))->native[i].fix_scnlen = 1;
}
- ppc_saw_abs = false;
+ ppc_saw_abs = FALSE;
}
/* Set the VMA for a section. This is called on all the sections in
ppc_fix_adjustable (fix)
fixS *fix;
{
- valueT val;
+ valueT val = resolve_symbol_value (fix->fx_addsy);
+ segT symseg = S_GET_SEGMENT (fix->fx_addsy);
+ TC_SYMFIELD_TYPE *tc;
+
+ if (symseg == absolute_section)
+ return 0;
- resolve_symbol_value (fix->fx_addsy);
- val = S_GET_VALUE (fix->fx_addsy);
if (ppc_toc_csect != (symbolS *) NULL
- && fix->fx_addsy != (symbolS *) NULL
&& fix->fx_addsy != ppc_toc_csect
- && S_GET_SEGMENT (fix->fx_addsy) == data_section
+ && symseg == data_section
&& val >= ppc_toc_frag->fr_address
&& (ppc_after_toc_frag == (fragS *) NULL
|| val < ppc_after_toc_frag->fr_address))
sy != (symbolS *) NULL;
sy = symbol_next (sy))
{
- if (symbol_get_tc (sy)->class == XMC_TC0)
+ TC_SYMFIELD_TYPE *sy_tc = symbol_get_tc (sy);
+
+ if (sy_tc->class == XMC_TC0)
continue;
- if (symbol_get_tc (sy)->class != XMC_TC)
+ if (sy_tc->class != XMC_TC)
break;
- resolve_symbol_value (sy);
- if (val == S_GET_VALUE (sy))
+ if (val == resolve_symbol_value (sy))
{
fix->fx_addsy = sy;
fix->fx_addnumber = val - ppc_toc_frag->fr_address;
}
/* Possibly adjust the reloc to be against the csect. */
- if (fix->fx_addsy != (symbolS *) NULL
- && symbol_get_tc (fix->fx_addsy)->subseg == 0
- && symbol_get_tc (fix->fx_addsy)->class != XMC_TC0
- && symbol_get_tc (fix->fx_addsy)->class != XMC_TC
- && S_GET_SEGMENT (fix->fx_addsy) != bss_section
+ tc = symbol_get_tc (fix->fx_addsy);
+ if (tc->subseg == 0
+ && tc->class != XMC_TC0
+ && tc->class != XMC_TC
+ && symseg != bss_section
/* Don't adjust if this is a reloc in the toc section. */
- && (S_GET_SEGMENT (fix->fx_addsy) != data_section
+ && (symseg != data_section
|| ppc_toc_csect == NULL
|| val < ppc_toc_frag->fr_address
|| (ppc_after_toc_frag != NULL
&& val >= ppc_after_toc_frag->fr_address)))
{
symbolS *csect;
+ symbolS *next_csect;
- if (S_GET_SEGMENT (fix->fx_addsy) == text_section)
+ if (symseg == text_section)
csect = ppc_text_csects;
- else if (S_GET_SEGMENT (fix->fx_addsy) == data_section)
+ else if (symseg == data_section)
csect = ppc_data_csects;
else
abort ();
if (csect != (symbolS *) NULL)
{
- while (symbol_get_tc (csect)->next != (symbolS *) NULL
- && (symbol_get_frag (symbol_get_tc (csect)->next)->fr_address
- <= val))
+ while ((next_csect = symbol_get_tc (csect)->next) != (symbolS *) NULL
+ && (symbol_get_frag (next_csect)->fr_address <= val))
{
/* If the csect address equals the symbol value, then we
have to look through the full symbol table to see
whether this is the csect we want. Note that we will
only get here if the csect has zero length. */
- if ((symbol_get_frag (csect)->fr_address == val)
- && S_GET_VALUE (csect) == S_GET_VALUE (fix->fx_addsy))
+ if (symbol_get_frag (csect)->fr_address == val
+ && S_GET_VALUE (csect) == val)
{
symbolS *scan;
break;
}
- csect = symbol_get_tc (csect)->next;
+ csect = next_csect;
}
- fix->fx_offset += (S_GET_VALUE (fix->fx_addsy)
- - symbol_get_frag (csect)->fr_address);
+ fix->fx_offset += val - symbol_get_frag (csect)->fr_address;
fix->fx_addsy = csect;
}
+ return 0;
}
/* Adjust a reloc against a .lcomm symbol to be against the base
.lcomm. */
- if (fix->fx_addsy != (symbolS *) NULL
- && S_GET_SEGMENT (fix->fx_addsy) == bss_section
+ if (symseg == bss_section
&& ! S_IS_EXTERNAL (fix->fx_addsy))
{
- resolve_symbol_value (symbol_get_frag (fix->fx_addsy)->fr_symbol);
- fix->fx_offset +=
- (S_GET_VALUE (fix->fx_addsy)
- - S_GET_VALUE (symbol_get_frag (fix->fx_addsy)->fr_symbol));
- fix->fx_addsy = symbol_get_frag (fix->fx_addsy)->fr_symbol;
+ symbolS *sy = symbol_get_frag (fix->fx_addsy)->fr_symbol;
+
+ fix->fx_offset += val - resolve_symbol_value (sy);
+ fix->fx_addsy = sy;
}
return 0;
<= fix->fx_frag->fr_address))))
return 1;
- return 0;
+ return S_FORCE_RELOC (fix->fx_addsy);
}
#endif /* OBJ_XCOFF */
#ifdef OBJ_ELF
+/* If this function returns non-zero, it guarantees that a relocation
+ will be emitted for a fixup. */
+
+int
+ppc_force_relocation (fix)
+ fixS *fix;
+{
+ /* Branch prediction relocations must force a relocation, as must
+ the vtable description relocs. */
+ switch (fix->fx_r_type)
+ {
+ case BFD_RELOC_PPC_B16_BRTAKEN:
+ case BFD_RELOC_PPC_B16_BRNTAKEN:
+ case BFD_RELOC_PPC_BA16_BRTAKEN:
+ case BFD_RELOC_PPC_BA16_BRNTAKEN:
+ case BFD_RELOC_PPC64_TOC:
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ return 1;
+ default:
+ break;
+ }
+
+ return S_FORCE_RELOC (fix->fx_addsy);
+}
+
int
ppc_fix_adjustable (fix)
fixS *fix;
&& fix->fx_r_type != BFD_RELOC_GPREL16
&& fix->fx_r_type != BFD_RELOC_VTABLE_INHERIT
&& fix->fx_r_type != BFD_RELOC_VTABLE_ENTRY
- && ! S_IS_EXTERNAL (fix->fx_addsy)
- && ! S_IS_WEAK (fix->fx_addsy)
&& (fix->fx_pcrel
|| (fix->fx_subsy != NULL
&& (S_GET_SEGMENT (fix->fx_subsy)
#ifdef OBJ_ELF
if (fixP->fx_addsy != NULL)
{
- /* `*valuep' may contain the value of the symbol on which the reloc
- will be based; we have to remove it. */
- if (symbol_used_in_reloc_p (fixP->fx_addsy)
- && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section
- && S_GET_SEGMENT (fixP->fx_addsy) != undefined_section
- && ! bfd_is_com_section (S_GET_SEGMENT (fixP->fx_addsy)))
- value -= S_GET_VALUE (fixP->fx_addsy);
-
- /* FIXME: Why '+'? Better yet, what exactly is '*valuep'
- supposed to be? I think this is related to various similar
- FIXMEs in tc-i386.c and tc-sparc.c. */
+ /* Hack around bfd_install_relocation brain damage. */
if (fixP->fx_pcrel)
value += fixP->fx_frag->fr_address + fixP->fx_where;
}
else
fixP->fx_done = 1;
#else
- /* FIXME FIXME FIXME: The value we are passed in *valuep includes
+ /* FIXME FIXME FIXME: The value we are passed in *valP includes
the symbol values. Since we are using BFD_ASSEMBLER, if we are
doing this relocation the code in write.c is going to call
bfd_install_relocation, which is also going to use the symbol
value. That means that if the reloc is fully resolved we want to
- use *valuep since bfd_install_relocation is not being used.
+ use *valP since bfd_install_relocation is not being used.
However, if the reloc is not fully resolved we do not want to use
- *valuep, and must use fx_offset instead. However, if the reloc
- is PC relative, we do want to use *valuep since it includes the
+ *valP, and must use fx_offset instead. However, if the reloc
+ is PC relative, we do want to use *valP since it includes the
result of md_pcrel_from. This is confusing. */
if (fixP->fx_addsy == (symbolS *) NULL)
fixP->fx_done = 1;
;
else
+ value = fixP->fx_offset;
+#endif
+
+ if (fixP->fx_subsy != (symbolS *) NULL)
{
- value = fixP->fx_offset;
- if (fixP->fx_subsy != (symbolS *) NULL)
- {
- if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
- value -= S_GET_VALUE (fixP->fx_subsy);
- else
- {
- /* We can't actually support subtracting a symbol. */
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("expression too complex"));
- }
- }
+ /* We can't actually support subtracting a symbol. */
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
}
-#endif
if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
{
if ((operand->flags & PPC_OPERAND_PARENS) != 0
&& operand->bits == 16
&& operand->shift == 0
- && (operand->insert == NULL || ppc_xcoff64)
+ && (operand->insert == NULL || ppc_obj64)
&& fixP->fx_addsy != NULL
&& symbol_get_tc (fixP->fx_addsy)->subseg != 0
&& symbol_get_tc (fixP->fx_addsy)->class != XMC_TC
else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
&& operand->bits == 16
&& operand->shift == 0)
- fixP->fx_r_type = BFD_RELOC_PPC_B16;
+ {
+ fixP->fx_r_type = BFD_RELOC_PPC_B16;
+#ifdef OBJ_XCOFF
+ fixP->fx_size = 2;
+ if (target_big_endian)
+ fixP->fx_where += 2;
+#endif
+ }
else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
&& operand->bits == 26
&& operand->shift == 0)
else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
&& operand->bits == 16
&& operand->shift == 0)
- fixP->fx_r_type = BFD_RELOC_PPC_BA16;
+ {
+ fixP->fx_r_type = BFD_RELOC_PPC_BA16;
+#ifdef OBJ_XCOFF
+ fixP->fx_size = 2;
+ if (target_big_endian)
+ fixP->fx_where += 2;
+#endif
+ }
#if defined (OBJ_XCOFF) || defined (OBJ_ELF)
else if ((operand->flags & PPC_OPERAND_PARENS) != 0
&& operand->bits == 16
{
fixP->fx_r_type = BFD_RELOC_PPC_TOC16;
#ifdef OBJ_ELF
- if (BFD_DEFAULT_TARGET_SIZE == 64
- && ppc_size == PPC_OPCODE_64
+ if (ppc_obj64
&& (operand->flags & PPC_OPERAND_DS) != 0)
fixP->fx_r_type = BFD_RELOC_PPC64_TOC16_DS;
#endif
switch (fixP->fx_r_type)
{
case BFD_RELOC_CTOR:
- if (BFD_DEFAULT_TARGET_SIZE == 64 && ppc_size == PPC_OPCODE_64)
+ if (ppc_obj64)
goto ctor64;
/* fall through */
case BFD_RELOC_PPC_EMB_RELSDA:
case BFD_RELOC_PPC_TOC16:
#ifdef OBJ_ELF
-#if BFD_DEFAULT_TARGET_SIZE == 64
case BFD_RELOC_PPC64_TOC16_LO:
case BFD_RELOC_PPC64_TOC16_HI:
case BFD_RELOC_PPC64_TOC16_HA:
-#endif
#endif
if (fixP->fx_pcrel)
{
break;
#ifdef OBJ_ELF
-#if BFD_DEFAULT_TARGET_SIZE == 64
case BFD_RELOC_PPC64_HIGHER:
if (fixP->fx_pcrel)
abort ();
bfd_putl16 ((bfd_vma) val, where);
}
break;
-#endif
#endif
/* Because SDA21 modifies the register field, the size is set to 4
bytes, rather than 2, so offset it here appropriately. */
break;
#ifdef OBJ_ELF
-#if BFD_DEFAULT_TARGET_SIZE == 64
/* Generated by reference to `sym@tocbase'. The sym is
ignored by the linker. */
case BFD_RELOC_PPC64_TOC:
fixP->fx_done = 0;
break;
-#endif
#endif
default:
fprintf (stderr,