/* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000)
- Copyright (C) 1994-2015 Free Software Foundation, Inc.
+ Copyright (C) 1994-2016 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of GAS, the GNU Assembler.
/* Structure to hold information about predefined registers. */
struct pd_reg
{
- char *name;
+ const char *name;
int value;
};
const size_t md_longopts_size = sizeof (md_longopts);
int
-md_parse_option (int c, char *arg)
+md_parse_option (int c, const char *arg)
{
ppc_cpu_t new_cpu;
-mpower6, -mpwr6 generate code for Power6 architecture\n\
-mpower7, -mpwr7 generate code for Power7 architecture\n\
-mpower8, -mpwr8 generate code for Power8 architecture\n\
+-mpower9, -mpwr9 generate code for Power9 architecture\n\
-mcell generate code for Cell Broadband Engine architecture\n\
-mcom generate code Power/PowerPC common instructions\n\
-many generate code for any architecture (PWR/PWRX/PPC)\n"));
return bfd_mach_ppc;
}
-extern char*
+extern const char*
ppc_target_format (void)
{
#ifdef OBJ_COFF
const struct powerpc_operand *operand,
offsetT val,
ppc_cpu_t cpu,
- char *file,
+ const char *file,
unsigned int line)
{
long min, max, right;
ppc_elf_suffix (char **str_p, expressionS *exp_p)
{
struct map_bfd {
- char *string;
+ const char *string;
unsigned int length : 8;
unsigned int valid32 : 1;
unsigned int valid64 : 1;
const char *name;
char *dotname;
symbolS *dotsym;
- size_t len;
name = S_GET_NAME (symp);
if (name[0] == '.')
|| S_IS_DEFINED (symp))
continue;
- len = strlen (name) + 1;
- dotname = xmalloc (len + 1);
- dotname[0] = '.';
- memcpy (dotname + 1, name, len);
+ dotname = concat (".", name, (char *) NULL);
dotsym = symbol_find_noref (dotname, 1);
free (dotname);
if (dotsym != NULL && (symbol_used_p (dotsym)
break;
}
+ /* addpcis. */
+ if (opcode->opcode == (19 << 26) + (2 << 1)
+ && reloc == BFD_RELOC_HI16_S)
+ reloc = BFD_RELOC_PPC_REL16DX_HA;
+
/* If VLE-mode convert LO/HI/HA relocations. */
if (opcode->flags & PPC_OPCODE_VLE)
{
}
/* Put the string together. */
- complete = s = (char *) alloca (len + 1);
+ complete = s = (char *) xmalloc (len + 1);
format = macro->format;
while (*format != '\0')
{
/* Assemble the constructed instruction. */
md_assemble (complete);
+ free (complete);
}
\f
#ifdef OBJ_ELF
/* Strip out the symbol name. */
c = get_symbol_name (&symbol_name);
- name = xmalloc (input_line_pointer - symbol_name + 1);
- strcpy (name, symbol_name);
+ name = xstrdup (symbol_name);
sym = symbol_find_or_make (name);
c = get_symbol_name (§ion_name);
- name = xmalloc (input_line_pointer - section_name + 1);
- strcpy (name, section_name);
+ name = xstrdup (section_name);
*input_line_pointer = c;
char *snew;
len = s - name;
- snew = xmalloc (len + 1);
- memcpy (snew, name, len);
- snew[len] = '\0';
+ snew = xstrndup (name, len);
S_SET_NAME (sym, snew);
}
#endif /* OBJ_XCOFF */
\f
-char *
+const char *
md_atof (int type, char *litp, int *sizep)
{
return ieee_md_atof (type, litp, sizep, target_big_endian);
if ((ppc_cpu & PPC_OPCODE_POWER6) != 0
|| (ppc_cpu & PPC_OPCODE_POWER7) != 0
- || (ppc_cpu & PPC_OPCODE_POWER8) != 0)
+ || (ppc_cpu & PPC_OPCODE_POWER8) != 0
+ || (ppc_cpu & PPC_OPCODE_POWER9) != 0)
{
- /* For power6, power7 and power8, we want the last nop to be a group
- terminating one. Do this by inserting an rs_fill frag immediately
- after this one, with its address set to the last nop location.
- This will automatically reduce the number of nops in the current
- frag by one. */
+ /* For power6, power7, power8 and power9, we want the last nop to be
+ a group terminating one. Do this by inserting an rs_fill frag
+ immediately after this one, with its address set to the last nop
+ location. This will automatically reduce the number of nops in
+ the current frag by one. */
if (count > 4)
{
struct frag *group_nop = xmalloc (SIZEOF_STRUCT_FRAG + 4);
}
if ((ppc_cpu & PPC_OPCODE_POWER7) != 0
- || (ppc_cpu & PPC_OPCODE_POWER8) != 0)
+ || (ppc_cpu & PPC_OPCODE_POWER8) != 0
+ || (ppc_cpu & PPC_OPCODE_POWER9) != 0)
{
if (ppc_cpu & PPC_OPCODE_E500MC)
/* e500mc group terminating nop: "ori 0,0,0". */
md_number_to_chars (dest, 0x60000000, 4);
else
- /* power7/power8 group terminating nop: "ori 2,2,0". */
+ /* power7/power8/power9 group terminating nop: "ori 2,2,0". */
md_number_to_chars (dest, 0x60420000, 4);
}
else
/* Hack around bfd_install_relocation brain damage. */
if (fixP->fx_pcrel)
value += fixP->fx_frag->fr_address + fixP->fx_where;
+
+ if (fixP->fx_addsy == abs_section_sym)
+ fixP->fx_done = 1;
}
else
fixP->fx_done = 1;
case BFD_RELOC_HI16_S:
case BFD_RELOC_HI16_S_PCREL:
+ case BFD_RELOC_PPC_REL16DX_HA:
#ifdef OBJ_ELF
if (REPORT_OVERFLOW_HI && ppc_obj64)
{
if (operand != NULL)
{
/* Handle relocs in an insn. */
- char *where;
- unsigned long insn;
-
switch (fixP->fx_r_type)
{
#ifdef OBJ_ELF
#endif
if ((fieldval != 0 && APPLY_RELOC) || operand->insert != NULL)
{
+ unsigned long insn;
+ unsigned char *where;
+
/* Fetch the instruction, insert the fully resolved operand
value, and stuff the instruction back again. */
- where = fixP->fx_frag->fr_literal + fixP->fx_where;
+ where = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
if (target_big_endian)
{
if (fixP->fx_size == 4)
- insn = bfd_getb32 ((unsigned char *) where);
+ insn = bfd_getb32 (where);
else
- insn = bfd_getb16 ((unsigned char *) where);
+ insn = bfd_getb16 (where);
}
else
{
if (fixP->fx_size == 4)
- insn = bfd_getl32 ((unsigned char *) where);
+ insn = bfd_getl32 (where);
else
- insn = bfd_getl16 ((unsigned char *) where);
+ insn = bfd_getl16 (where);
}
insn = ppc_insert_operand (insn, operand, fieldval,
fixP->tc_fix_data.ppc_cpu,
if (target_big_endian)
{
if (fixP->fx_size == 4)
- bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ bfd_putb32 (insn, where);
else
- bfd_putb16 ((bfd_vma) insn, (unsigned char *) where);
+ bfd_putb16 (insn, where);
}
else
{
if (fixP->fx_size == 4)
- bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+ bfd_putl32 (insn, where);
else
- bfd_putl16 ((bfd_vma) insn, (unsigned char *) where);
+ bfd_putl16 (insn, where);
}
}
gas_assert (fixP->fx_addsy != NULL);
if (fixP->fx_r_type == BFD_RELOC_NONE)
{
- char *sfile;
+ const char *sfile;
unsigned int sline;
/* Use expr_symbol_where to see if this is an expression
case BFD_RELOC_LO16_PCREL:
case BFD_RELOC_HI16_PCREL:
case BFD_RELOC_HI16_S_PCREL:
+ case BFD_RELOC_PPC_REL16DX_HA:
case BFD_RELOC_64_PCREL:
case BFD_RELOC_32_PCREL:
case BFD_RELOC_16_PCREL:
default:
if (fixP->fx_addsy)
{
- char *sfile;
+ const char *sfile;
unsigned int sline;
/* Use expr_symbol_where to see if this is an
unsigned int i;
const char *p;
char *q;
- static struct { char *name; int dw2regnum; } regnames[] =
+ static struct { const char *name; int dw2regnum; } regnames[] =
{
{ "sp", 1 }, { "r.sp", 1 }, { "rtoc", 2 }, { "r.toc", 2 },
{ "mq", 64 }, { "lr", 65 }, { "ctr", 66 }, { "ap", 67 },