diff options
-rw-r--r-- | gas/ChangeLog | 19 | ||||
-rw-r--r-- | gas/config/tc-ppc.c | 66 | ||||
-rw-r--r-- | gas/config/tc-ppc.h | 13 | ||||
-rw-r--r-- | gas/write.c | 55 |
4 files changed, 106 insertions, 47 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 523d6ef..1e59811 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,22 @@ +Tue Oct 24 14:50:38 1995 Michael Meissner <meissner@tiktok.cygnus.com> + + * config/tc-ppc.h (TC_FORCE_RELOCATION_SECTION): Rename from + TC_FORCE_RELOCATION, taking an additional section argument. If + the section of the target symbol is not the same as the current + section, always force the relocation to be used. + (MD_PCREL_FROM_SECTION): New macro to call md_pcrel_from_section. + + * config/tc-ppc.c (md_pcrel_from_section): Rename from the + md_pcrel_from function, taking an additional section argument. + Invoke TC_FORCE_RELOCATION_SECTION instead of TC_FORCE_RELOCATION. + + * write.c (TC_FORCE_RELOCATION_SECTION): Define in terms of the + older TC_FORCE_RELOCATION if not defined. + (MD_PCREL_FROM_SECTION): If not defined, invoke md_pcrel_from. + (fixup_segment): Use MD_PCREL_FROM_SECTION instead of + md_pcrel_from, and TC_FORCE_RELOCATION_SECTION instead of + TC_FORCE_RELOCATION. + Mon Oct 23 16:20:04 1995 Ken Raeburn <raeburn@cygnus.com> * input-scrub.c (as_where): Set name to null pointer if we don't diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 59405bc..f7cf199 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -561,10 +561,8 @@ md_parse_option (c, arg) /* -mpwr means to assemble for the IBM POWER (RIOS1). */ else if (strcmp (arg, "pwr") == 0) ppc_cpu = PPC_OPCODE_POWER; - /* -m601 means to assemble for the Motorola PowerPC 601. FIXME: We - ignore the option for now, but we should really use it to permit - instructions defined on the 601 that are not part of the standard - PowerPC architecture (mostly holdovers from the POWER). */ + /* -m601 means to assemble for the Motorola 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; /* -mppc, -mppc32, -m603, and -m604 mean to assemble for the @@ -586,10 +584,10 @@ md_parse_option (c, arg) and PowerPC. At present, we just allow the union, rather than the intersection. */ else if (strcmp (arg, "com") == 0) - ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_PPC; + ppc_cpu = PPC_OPCODE_COMMON; /* -many means to assemble for any architecture (PWR/PWRX/PPC). */ else if (strcmp (arg, "any") == 0) - ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_PPC; + ppc_cpu = PPC_OPCODE_ANY; #ifdef OBJ_ELF /* -mrelocatable/-mrelocatable-lib -- warn about initializations that require relocation */ @@ -700,17 +698,24 @@ ppc_set_cpu () enum bfd_architecture ppc_arch () { + const char *default_cpu = TARGET_CPU; ppc_set_cpu (); if ((ppc_cpu & PPC_OPCODE_PPC) != 0) return bfd_arch_powerpc; else if ((ppc_cpu & PPC_OPCODE_POWER) != 0) return bfd_arch_rs6000; - else + else if ((ppc_cpu & (PPC_OPCODE_COMMON | PPC_OPCODE_ANY)) != 0) { - as_fatal ("Neither Power nor PowerPC opcodes were selected."); - return bfd_arch_unknown; + if (strcmp (default_cpu, "rs6000") == 0) + return bfd_arch_rs6000; + else if (strcmp (default_cpu, "powerpc") == 0 + || strcmp (default_cpu, "powerpcle") == 0) + return bfd_arch_powerpc; } + + as_fatal ("Neither Power nor PowerPC opcodes were selected."); + return bfd_arch_unknown; } /* This function is called when the assembler starts up. It is called @@ -724,6 +729,7 @@ md_begin () const struct powerpc_opcode *op_end; const struct powerpc_macro *macro; const struct powerpc_macro *macro_end; + boolean dup_insn = false; ppc_set_cpu (); @@ -750,28 +756,13 @@ md_begin () retval = hash_insert (ppc_hash, op->name, (PTR) op); if (retval != (const char *) NULL) { - /* We permit a duplication of the mfdec instruction on - the 601, because it seems to have one value on the - 601 and a different value on other PowerPC - processors. It's easier to permit a duplication than - to define a new instruction type flag. When using - -many/-mcom, the comparison instructions are a harmless - special case. */ - if (strcmp (retval, "exists") != 0 - || ((((ppc_cpu & PPC_OPCODE_601) == 0 - && ((ppc_cpu & ~PPC_OPCODE_POWER2) - == (PPC_OPCODE_POWER | PPC_OPCODE_PPC))) - || strcmp (op->name, "mfdec") != 0) - && (((ppc_cpu & ~PPC_OPCODE_POWER2) - != (PPC_OPCODE_POWER | PPC_OPCODE_PPC)) - || (strcmp (op->name, "cmpli") != 0 - && strcmp (op->name, "cmpi") != 0 - && strcmp (op->name, "cmp") != 0 - && strcmp (op->name, "cmpl") != 0)))) - { - as_bad ("Internal assembler error for instruction %s", op->name); - abort (); - } + /* Ignore Power duplicates for -m601 */ + if ((ppc_cpu & PPC_OPCODE_601) != 0 + && (op->flags & PPC_OPCODE_POWER) != 0) + continue; + + as_bad ("Internal assembler error for instruction %s", op->name); + dup_insn = true; } } } @@ -788,10 +779,16 @@ md_begin () retval = hash_insert (ppc_macro_hash, macro->name, (PTR) macro); if (retval != (const char *) NULL) - abort (); + { + as_bad ("Internal assembler error for macro %s", macro->name); + dup_insn = true; + } } } + if (dup_insn) + abort (); + /* Tell the main code what the endianness is if it is not overidden by the user. */ if (!set_target_endian) { @@ -3756,13 +3753,14 @@ md_undefined_symbol (name) given a PC relative reloc. */ long -md_pcrel_from (fixp) +md_pcrel_from_section (fixp, sec) fixS *fixp; + segT sec; { #ifdef OBJ_ELF if (fixp->fx_addsy != (symbolS *) NULL && (! S_IS_DEFINED (fixp->fx_addsy) - || TC_FORCE_RELOCATION (fixp))) + || TC_FORCE_RELOCATION_SECTION (fixp, sec))) return 0; #endif diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index 1a456ae..cbedae4 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -102,6 +102,10 @@ extern int target_big_endian; /* Question marks are permitted in symbol names. */ #define LEX_QM 1 +/* Don't adjust TOC relocs. */ +#define tc_fix_adjustable(fixp) ppc_pe_fix_adjustable (fixp) +extern int ppc_pe_fix_adjustable PARAMS ((struct fix *)); + #endif #ifdef OBJ_XCOFF @@ -187,15 +191,20 @@ extern void ppc_frob_file PARAMS ((void)); #endif /* Branch prediction relocations must force relocation */ -#define TC_FORCE_RELOCATION(FIXP) \ +#define TC_FORCE_RELOCATION_SECTION(FIXP,SEC) \ ((FIXP)->fx_r_type == BFD_RELOC_PPC_B16_BRTAKEN \ || (FIXP)->fx_r_type == BFD_RELOC_PPC_B16_BRNTAKEN \ || (FIXP)->fx_r_type == BFD_RELOC_PPC_BA16_BRTAKEN \ - || (FIXP)->fx_r_type == BFD_RELOC_PPC_BA16_BRNTAKEN) + || (FIXP)->fx_r_type == BFD_RELOC_PPC_BA16_BRNTAKEN \ + || ((FIXP)->fx_addsy && !(FIXP)->fx_subsy && (FIXP)->fx_addsy->bsym \ + && (FIXP)->fx_addsy->bsym->section != SEC)) #endif /* OBJ_ELF */ /* call md_apply_fix3 with segment instead of md_apply_fix */ #define MD_APPLY_FIX3 +/* call md_pcrel_from_section, not md_pcrel_from */ +#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC) + #define md_operand(x) diff --git a/gas/write.c b/gas/write.c index 6dd4ff1..91871da 100644 --- a/gas/write.c +++ b/gas/write.c @@ -43,6 +43,14 @@ #define TC_FORCE_RELOCATION(FIXP) 0 #endif +#ifndef TC_FORCE_RELOCATION_SECTION +#define TC_FORCE_RELOCATION_SECTION(FIXP,SEG) TC_FORCE_RELOCATION(FIXP) +#endif + +#ifndef MD_PCREL_FROM_SECTION +#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from(FIXP) +#endif + #ifndef WORKING_DOT_WORD extern CONST int md_short_jump_size; extern CONST int md_long_jump_size; @@ -235,7 +243,7 @@ fix_new_exp (frag, where, size, exp, pcrel, r_type) symbolS *add = NULL; symbolS *sub = NULL; offsetT off = 0; - + switch (exp->X_op) { case O_absent: @@ -254,6 +262,19 @@ fix_new_exp (frag, where, size, exp, pcrel, r_type) return fix_new_exp (frag, where, size, exp, pcrel, r_type); } + case O_symbol_rva: + add = exp->X_add_symbol; + off = exp->X_add_number; + +#if defined(BFD_ASSEMBLER) + r_type = BFD_RELOC_RVA; +#elif defined(TC_RVA_RELOC) + r_type = TC_RVA_RELOC; +#else + as_fatal("rva not supported"); +#endif + break; + case O_uminus: sub = exp->X_add_symbol; off = exp->X_add_number; @@ -355,6 +376,7 @@ chain_frchains_together_1 (section, frchp) { prev_frag->fr_next = frchp->frch_root; prev_frag = frchp->frch_last; + assert (prev_frag->fr_type != 0); #ifdef BFD_ASSEMBLER if (frchp->fix_root != (fixS *) NULL) { @@ -366,6 +388,7 @@ chain_frchains_together_1 (section, frchp) } #endif } + assert (prev_frag->fr_type != 0); prev_frag->fr_next = 0; return prev_frag; } @@ -2183,11 +2206,21 @@ fixup_segment (fixP, this_segment_type) if (sub_symbolP) { resolve_symbol_value (sub_symbolP); - if (!add_symbolP) + if (add_symbolP == NULL || add_symbol_segment == absolute_section) { - /* Its just -sym */ + if (add_symbolP != NULL) + { + add_number += S_GET_VALUE (add_symbolP); + add_symbolP = NULL; + fixP->fx_addsy = NULL; + } + + /* It's just -sym */ if (S_GET_SEGMENT (sub_symbolP) == absolute_section) - add_number -= S_GET_VALUE (sub_symbolP); + { + add_number -= S_GET_VALUE (sub_symbolP); + fixP->fx_subsy = NULL; + } else if (pcrel && S_GET_SEGMENT (sub_symbolP) == this_segment_type) { @@ -2200,9 +2233,8 @@ fixup_segment (fixP, this_segment_type) "Negative of non-absolute symbol %s", S_GET_NAME (sub_symbolP)); } - else if ((S_GET_SEGMENT (sub_symbolP) == add_symbol_segment) - && (SEG_NORMAL (add_symbol_segment) - || (add_symbol_segment == absolute_section))) + else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment + && SEG_NORMAL (add_symbol_segment)) { /* Difference of 2 symbols from same segment. Can't make difference of 2 undefineds: 'value' means @@ -2223,10 +2255,11 @@ fixup_segment (fixP, this_segment_type) /* Let the target machine make the final determination as to whether or not a relocation will be needed to handle this fixup. */ - if (!TC_FORCE_RELOCATION (fixP)) + if (!TC_FORCE_RELOCATION_SECTION (fixP, this_segment_type)) { fixP->fx_pcrel = 0; fixP->fx_addsy = NULL; + fixP->fx_subsy = NULL; } } else @@ -2248,7 +2281,7 @@ fixup_segment (fixP, this_segment_type) ) { /* Make it pc-relative. */ - add_number += (md_pcrel_from (fixP) + add_number += (MD_PCREL_FROM_SECTION (fixP, this_segment_type) - S_GET_VALUE (sub_symbolP)); pcrel = 1; fixP->fx_pcrel = 1; @@ -2304,7 +2337,7 @@ fixup_segment (fixP, this_segment_type) #endif /* TC_I960 */ add_number += S_GET_VALUE (add_symbolP); - add_number -= md_pcrel_from (fixP); + add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment_type); pcrel = 0; /* Lie. Don't want further pcrel processing. */ /* Let the target machine make the final determination @@ -2378,7 +2411,7 @@ fixup_segment (fixP, this_segment_type) if (pcrel) { - add_number -= md_pcrel_from (fixP); + add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment_type); if (add_symbolP == 0) { #ifndef BFD_ASSEMBLER |