X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-ppc.c;h=493bfe5546bd2a2b02663957955acd7ddfee0214;hb=c32fa91d70ea20b38f90e5a88911f796b9a6418c;hp=691d943421514c35db1ca17d5ab938b9b8662db3;hpb=69fe9ce501f5fde501443648fe4243dc9fe8d5b1;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 691d943421..493bfe5546 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -1188,6 +1188,7 @@ PowerPC options:\n\ -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")); @@ -1195,6 +1196,7 @@ PowerPC options:\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\ @@ -2527,7 +2529,7 @@ md_assemble (char *str) 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) { @@ -3338,7 +3340,7 @@ ppc_csect (int ignore ATTRIBUTE_UNUSED) 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; @@ -3374,7 +3376,7 @@ ppc_change_csect (symbolS *sym, offsetT align) 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: @@ -3764,8 +3766,8 @@ ppc_function (int ignore ATTRIBUTE_UNUSED) 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 == ',') @@ -4198,7 +4200,7 @@ ppc_tc (int ignore ATTRIBUTE_UNUSED) 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 (); @@ -4218,7 +4220,7 @@ ppc_tc (int ignore ATTRIBUTE_UNUSED) 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); @@ -4322,7 +4324,7 @@ static int 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)); @@ -4972,7 +4974,7 @@ ppc_symbol_new_hook (symbolS *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; @@ -4995,55 +4997,55 @@ ppc_symbol_new_hook (symbolS *sym) { 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")); } @@ -5056,8 +5058,8 @@ ppc_frob_label (symbolS *sym) { 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, @@ -5170,6 +5172,7 @@ ppc_frob_symbol (symbolS *sym) 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; @@ -5179,7 +5182,7 @@ ppc_frob_symbol (symbolS *sym) 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); @@ -5208,9 +5211,9 @@ ppc_frob_symbol (symbolS *sym) 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) { @@ -5218,8 +5221,8 @@ ppc_frob_symbol (symbolS *sym) 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)) { @@ -5227,17 +5230,17 @@ ppc_frob_symbol (symbolS *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, @@ -5297,10 +5300,10 @@ ppc_frob_symbol (symbolS *sym) 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; @@ -5505,9 +5508,9 @@ ppc_fix_adjustable (fixS *fix) { 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)) { @@ -5524,8 +5527,8 @@ ppc_fix_adjustable (fixS *fix) /* 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 @@ -5686,13 +5689,14 @@ ppc_handle_align (struct frag *fragP) 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); @@ -5706,7 +5710,12 @@ ppc_handle_align (struct frag *fragP) 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); } } } @@ -5741,18 +5750,19 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) 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) @@ -5783,8 +5793,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) && (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; @@ -5811,7 +5821,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) /* 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