expression. */
int
-ppc_parse_name (const char *name, expressionS *expr)
+ppc_parse_name (const char *name, expressionS *exp)
{
int val;
if (val < 0)
return 0;
- expr->X_op = O_constant;
- expr->X_add_number = val;
+ exp->X_op = O_constant;
+ exp->X_add_number = val;
return 1;
}
-m405 generate code for PowerPC 405\n\
-m440 generate code for PowerPC 440\n\
-m464 generate code for PowerPC 464\n\
+-m476 generate code for PowerPC 476\n\
-m7400, -m7410, -m7450, -m7455\n\
generate code for PowerPC 7400/7410/7450/7455\n\
-m750cl generate code for PowerPC 750cl\n"));
-mppc64, -m620 generate code for PowerPC 620/625/630\n\
-mppc64bridge generate code for PowerPC 64, including bridge insns\n\
-mbooke generate code for 32-bit PowerPC BookE\n\
+-ma2 generate code for A2 architecture\n\
-mpower4 generate code for Power4 architecture\n\
-mpower5 generate code for Power5 architecture\n\
-mpower6 generate code for Power6 architecture\n\
ppc_insert_operand (unsigned long insn,
const struct powerpc_operand *operand,
offsetT val,
- ppc_cpu_t ppc_cpu,
+ ppc_cpu_t cpu,
char *file,
unsigned int line)
{
const char *errmsg;
errmsg = NULL;
- insn = (*operand->insert) (insn, (long) val, ppc_cpu, &errmsg);
+ insn = (*operand->insert) (insn, (long) val, cpu, &errmsg);
if (errmsg != (const char *) NULL)
as_bad_where (file, line, "%s", errmsg);
}
{
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. */
explain. */
if (ex.X_op == O_symbol)
{
- assert (ex.X_add_symbol != NULL);
+ gas_assert (ex.X_add_symbol != NULL);
if (symbol_get_bfdsym (ex.X_add_symbol)->section
!= tocdata_section)
{
break;
case BFD_RELOC_PPC_TLS:
- insn = ppc_insert_operand (insn, operand, ppc_obj64 ? 13 : 2,
- ppc_cpu, (char *) NULL, 0);
+ if (!_bfd_elf_ppc_at_tls_transform (opcode->opcode, 0))
+ as_bad (_("@tls may not be used with \"%s\" operands"),
+ opcode->name);
+ else if (operand->shift != 11)
+ as_bad (_("@tls may only be used in last operand"));
+ else
+ insn = ppc_insert_operand (insn, operand,
+ ppc_obj64 ? 13 : 2,
+ ppc_cpu, (char *) NULL, 0);
break;
/* We'll only use the 32 (or 64) bit form of these relocations
if (S_GET_NAME (sym)[0] == '\0')
{
/* An unnamed csect is assumed to be [PR]. */
- symbol_get_tc (sym)->class = XMC_PR;
+ symbol_get_tc (sym)->symbol_class = XMC_PR;
}
align = 2;
data section. */
after_toc = 0;
is_code = 0;
- switch (symbol_get_tc (sym)->class)
+ switch (symbol_get_tc (sym)->symbol_class)
{
case XMC_PR:
case XMC_RO:
symbol_set_value_expression (ext_sym, &exp);
}
- if (symbol_get_tc (ext_sym)->class == -1)
- symbol_get_tc (ext_sym)->class = XMC_PR;
+ if (symbol_get_tc (ext_sym)->symbol_class == -1)
+ symbol_get_tc (ext_sym)->symbol_class = XMC_PR;
symbol_get_tc (ext_sym)->output = 1;
if (*input_line_pointer == ',')
{
- expressionS ignore;
+ expressionS exp;
/* Ignore the third argument. */
++input_line_pointer;
- expression (&ignore);
+ expression (& exp);
if (*input_line_pointer == ',')
{
/* Ignore the fourth argument. */
++input_line_pointer;
- expression (&ignore);
+ expression (& exp);
if (*input_line_pointer == ',')
{
/* The fifth argument is the function size. */
symbolS *label;
label = symbol_get_tc (ppc_current_csect)->within;
- if (symbol_get_tc (label)->class != XMC_TC0)
+ if (symbol_get_tc (label)->symbol_class != XMC_TC0)
{
as_bad (_(".tc with no label"));
ignore_rest_of_line ();
S_SET_SEGMENT (sym, now_seg);
symbol_set_frag (sym, frag_now);
S_SET_VALUE (sym, (valueT) frag_now_fix ());
- symbol_get_tc (sym)->class = XMC_TC;
+ symbol_get_tc (sym)->symbol_class = XMC_TC;
symbol_get_tc (sym)->output = 1;
ppc_frob_label (sym);
ppc_is_toc_sym (symbolS *sym)
{
#ifdef OBJ_XCOFF
- return symbol_get_tc (sym)->class == XMC_TC;
+ return symbol_get_tc (sym)->symbol_class == XMC_TC;
#endif
#ifdef OBJ_ELF
const char *sname = segment_name (S_GET_SEGMENT (sym));
tc = symbol_get_tc (sym);
tc->next = NULL;
tc->output = 0;
- tc->class = -1;
+ tc->symbol_class = -1;
tc->real_name = NULL;
tc->subseg = 0;
tc->align = 0;
{
case 'B':
if (strcmp (s, "BS]") == 0)
- tc->class = XMC_BS;
+ tc->symbol_class = XMC_BS;
break;
case 'D':
if (strcmp (s, "DB]") == 0)
- tc->class = XMC_DB;
+ tc->symbol_class = XMC_DB;
else if (strcmp (s, "DS]") == 0)
- tc->class = XMC_DS;
+ tc->symbol_class = XMC_DS;
break;
case 'G':
if (strcmp (s, "GL]") == 0)
- tc->class = XMC_GL;
+ tc->symbol_class = XMC_GL;
break;
case 'P':
if (strcmp (s, "PR]") == 0)
- tc->class = XMC_PR;
+ tc->symbol_class = XMC_PR;
break;
case 'R':
if (strcmp (s, "RO]") == 0)
- tc->class = XMC_RO;
+ tc->symbol_class = XMC_RO;
else if (strcmp (s, "RW]") == 0)
- tc->class = XMC_RW;
+ tc->symbol_class = XMC_RW;
break;
case 'S':
if (strcmp (s, "SV]") == 0)
- tc->class = XMC_SV;
+ tc->symbol_class = XMC_SV;
break;
case 'T':
if (strcmp (s, "TC]") == 0)
- tc->class = XMC_TC;
+ tc->symbol_class = XMC_TC;
else if (strcmp (s, "TI]") == 0)
- tc->class = XMC_TI;
+ tc->symbol_class = XMC_TI;
else if (strcmp (s, "TB]") == 0)
- tc->class = XMC_TB;
+ tc->symbol_class = XMC_TB;
else if (strcmp (s, "TC0]") == 0 || strcmp (s, "T0]") == 0)
- tc->class = XMC_TC0;
+ tc->symbol_class = XMC_TC0;
break;
case 'U':
if (strcmp (s, "UA]") == 0)
- tc->class = XMC_UA;
+ tc->symbol_class = XMC_UA;
else if (strcmp (s, "UC]") == 0)
- tc->class = XMC_UC;
+ tc->symbol_class = XMC_UC;
break;
case 'X':
if (strcmp (s, "XO]") == 0)
- tc->class = XMC_XO;
+ tc->symbol_class = XMC_XO;
break;
}
- if (tc->class == -1)
+ if (tc->symbol_class == -1)
as_bad (_("Unrecognized symbol suffix"));
}
{
if (ppc_current_csect != (symbolS *) NULL)
{
- if (symbol_get_tc (sym)->class == -1)
- symbol_get_tc (sym)->class = symbol_get_tc (ppc_current_csect)->class;
+ if (symbol_get_tc (sym)->symbol_class == -1)
+ symbol_get_tc (sym)->symbol_class = symbol_get_tc (ppc_current_csect)->symbol_class;
symbol_remove (sym, &symbol_rootP, &symbol_lastP);
symbol_append (sym, symbol_get_tc (ppc_current_csect)->within,
S_SET_STORAGE_CLASS (sym, C_HIDEXT);
if (S_GET_STORAGE_CLASS (sym) == C_EXT
+ || S_GET_STORAGE_CLASS (sym) == C_AIX_WEAKEXT
|| S_GET_STORAGE_CLASS (sym) == C_HIDEXT)
{
int i;
i = S_GET_NUMBER_AUXILIARY (sym);
S_SET_NUMBER_AUXILIARY (sym, i + 1);
a = &coffsymbol (symbol_get_bfdsym (sym))->native[i + 1].u.auxent;
- if (symbol_get_tc (sym)->class == XMC_TC0)
+ if (symbol_get_tc (sym)->symbol_class == XMC_TC0)
{
/* This is the TOC table. */
know (strcmp (S_GET_NAME (sym), "TOC") == 0);
a->x_csect.x_scnlen.l = symbol_get_frag (sym)->fr_offset;
a->x_csect.x_smtyp = (symbol_get_tc (sym)->align << 3) | XTY_CM;
if (S_IS_EXTERNAL (sym))
- symbol_get_tc (sym)->class = XMC_RW;
+ symbol_get_tc (sym)->symbol_class = XMC_RW;
else
- symbol_get_tc (sym)->class = XMC_BS;
+ symbol_get_tc (sym)->symbol_class = XMC_BS;
}
else if (S_GET_SEGMENT (sym) == absolute_section)
{
ppc_adjust_symtab. */
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;
+ if (symbol_get_tc (sym)->symbol_class == -1)
+ symbol_get_tc (sym)->symbol_class = XMC_XO;
}
else if (! S_IS_DEFINED (sym))
{
a->x_csect.x_scnlen.l = 0;
a->x_csect.x_smtyp = XTY_ER;
}
- else if (symbol_get_tc (sym)->class == XMC_TC)
+ else if (symbol_get_tc (sym)->symbol_class == XMC_TC)
{
symbolS *next;
/* This is a TOC definition. x_scnlen is the size of the
TOC entry. */
next = symbol_next (sym);
- while (symbol_get_tc (next)->class == XMC_TC0)
+ while (symbol_get_tc (next)->symbol_class == XMC_TC0)
next = symbol_next (next);
if (next == (symbolS *) NULL
- || symbol_get_tc (next)->class != XMC_TC)
+ || symbol_get_tc (next)->symbol_class != XMC_TC)
{
if (ppc_after_toc_frag == (fragS *) NULL)
a->x_csect.x_scnlen.l = (bfd_section_size (stdoutput,
a->x_csect.x_parmhash = 0;
a->x_csect.x_snhash = 0;
- if (symbol_get_tc (sym)->class == -1)
+ if (symbol_get_tc (sym)->symbol_class == -1)
a->x_csect.x_smclas = XMC_PR;
else
- a->x_csect.x_smclas = symbol_get_tc (sym)->class;
+ a->x_csect.x_smclas = symbol_get_tc (sym)->symbol_class;
a->x_csect.x_stab = 0;
a->x_csect.x_snstab = 0;
{
TC_SYMFIELD_TYPE *sy_tc = symbol_get_tc (sy);
- if (sy_tc->class == XMC_TC0)
+ if (sy_tc->symbol_class == XMC_TC0)
continue;
- if (sy_tc->class != XMC_TC)
+ if (sy_tc->symbol_class != XMC_TC)
break;
if (val == resolve_symbol_value (sy))
{
/* Possibly adjust the reloc to be against the csect. */
tc = symbol_get_tc (fix->fx_addsy);
if (tc->subseg == 0
- && tc->class != XMC_TC0
- && tc->class != XMC_TC
+ && tc->symbol_class != XMC_TC0
+ && tc->symbol_class != XMC_TC
&& symseg != bss_section
/* Don't adjust if this is a reloc in the toc section. */
&& (symseg != data_section
fragP->fr_var = 4;
md_number_to_chars (dest, 0x60000000, 4);
- if ((ppc_cpu & PPC_OPCODE_POWER6) != 0)
+ if ((ppc_cpu & PPC_OPCODE_POWER6) != 0
+ || (ppc_cpu & PPC_OPCODE_POWER7) != 0)
{
- /* For power6, we want the last nop to be a group terminating
- one, "ori 1,1,0". 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 and power7, 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);
dest = group_nop->fr_literal;
}
- md_number_to_chars (dest, 0x60210000, 4);
+ if ((ppc_cpu & PPC_OPCODE_POWER7) != 0)
+ /* power7 group terminating nop: "ori 2,2,0". */
+ md_number_to_chars (dest, 0x60420000, 4);
+ else
+ /* power6 group terminating nop: "ori 1,1,0". */
+ md_number_to_chars (dest, 0x60210000, 4);
}
}
}
going to use the symbol value. That means that if the reloc is
fully resolved we want to use *valP since bfd_install_relocation is
not being used.
- However, if the reloc is not fully resolved we do not want to use
- *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. */
+ However, if the reloc is not fully resolved we do not want to
+ use *valP, and must use fx_offset instead. If the relocation
+ is PC-relative, we then need to re-apply md_pcrel_from_section
+ to this new relocation value. */
if (fixP->fx_addsy == (symbolS *) NULL)
fixP->fx_done = 1;
- else if (fixP->fx_pcrel)
- ;
-
else
- value = fixP->fx_offset;
+ {
+ value = fixP->fx_offset;
+ if (fixP->fx_pcrel)
+ value -= md_pcrel_from_section (fixP, seg);
+ }
#endif
if (fixP->fx_subsy != (symbolS *) NULL)
&& (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
- && symbol_get_tc (fixP->fx_addsy)->class != XMC_TC0
+ && symbol_get_tc (fixP->fx_addsy)->symbol_class != XMC_TC
+ && symbol_get_tc (fixP->fx_addsy)->symbol_class != XMC_TC0
&& S_GET_SEGMENT (fixP->fx_addsy) != bss_section)
{
value = fixP->fx_offset;
/* Nothing else to do here. */
return;
- assert (fixP->fx_addsy != NULL);
+ gas_assert (fixP->fx_addsy != NULL);
/* Determine a BFD reloc value based on the operand information.
We are only prepared to turn a few of the operands into