From a7aa7a2ba9d572c6ff085f28d540cd623214c63b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 5 Jul 1995 21:52:10 +0000 Subject: [PATCH] * config/tc-sparc.c (md_shortopts): Add "K:" if OBJ_ELF. (md_parse_option): If OBJ_ELF, check for -K. Die if -K PIC, since PIC code is not currently supported. * as.c (parse_args): Change std_shortopts to be an array rather than a constant string. Only include 'K' if WORKING_DOT_WORD is not defined. Only check for 'K' in that case as well. * as.h (flag_warn_displacement): Only declare if WORKING_DOT_WORD is not defined. PR 7131. --- gas/ChangeLog | 10 ++++ gas/as.c | 23 ++++++--- gas/as.h | 5 ++ gas/config/tc-sparc.c | 105 +++++++++++++++++++++--------------------- 4 files changed, 85 insertions(+), 58 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 57a14261bd..121d05d8bc 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,15 @@ Wed Jul 5 12:01:49 1995 Ian Lance Taylor + * config/tc-sparc.c (md_shortopts): Add "K:" if OBJ_ELF. + (md_parse_option): If OBJ_ELF, check for -K. Die if -K PIC, since + PIC code is not currently supported. + + * as.c (parse_args): Change std_shortopts to be an array rather + than a constant string. Only include 'K' if WORKING_DOT_WORD is + not defined. Only check for 'K' in that case as well. + * as.h (flag_warn_displacement): Only declare if WORKING_DOT_WORD + is not defined. + * conf.in: Add undef of HAVE_SBRK. * config/obj-coff.c (obj_coff_line): Call listing_source_line, in diff --git a/gas/as.c b/gas/as.c index 5a937b38eb..d439a95bb5 100644 --- a/gas/as.c +++ b/gas/as.c @@ -214,13 +214,22 @@ parse_args (pargc, pargv) char *shortopts; extern CONST char *md_shortopts; -#ifdef VMS - /* -v takes an argument on VMS, so we don't make it a generic option. */ - CONST char *std_shortopts = "-JKLRWZfa::DI:o:wX"; -#else - CONST char *std_shortopts = "-JKLRWZfa::DI:o:vwX"; + static const char std_shortopts[] = + { + '-', 'J', +#ifndef WORKING_DOT_WORD + /* -K is not meaningful if .word is not being hacked. */ + 'K', #endif - + 'L', 'R', 'W', 'Z', 'f', 'a', ':', ':', 'D', 'I', ':', 'o', ':', +#ifndef VMS + /* -v takes an argument on VMS, so we don't make it a generic + option. */ + 'v', +#endif + 'w', 'X', + '\0' + }; struct option *longopts; extern struct option md_longopts[]; extern size_t md_longopts_size; @@ -348,9 +357,11 @@ parse_args (pargc, pargv) flag_signed_overflow_ok = 1; break; +#ifndef WORKING_DOT_WORD case 'K': flag_warn_displacement = 1; break; +#endif case 'L': flag_keep_locals = 1; diff --git a/gas/as.h b/gas/as.h index 7477388a72..252106c5f0 100644 --- a/gas/as.h +++ b/gas/as.h @@ -473,7 +473,9 @@ COMMON fragS bss_address_frag; COMMON unsigned char flag_no_comments; /* -f */ COMMON unsigned char flag_debug; /* -D */ COMMON unsigned char flag_signed_overflow_ok; /* -J */ +#ifndef WORKING_DOT_WORD COMMON unsigned char flag_warn_displacement; /* -K */ +#endif /* True if local symbols should be retained. */ COMMON unsigned char flag_keep_locals; /* -L */ @@ -627,6 +629,9 @@ valueT add_to_literal_pool PARAMS ((struct symbol *, valueT, segT, int)); #include "tc.h" #include "obj.h" +#ifdef USE_EMULATIONS +#include "emul.h" +#endif #include "listing.h" #ifndef LOCAL_LABELS_DOLLAR diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index 5fa7d9dae6..5bfa901fc2 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -38,8 +38,6 @@ static int warn_on_bump; extern int target_big_endian; -const relax_typeS md_relax_table[1]; - /* handle of the OPCODE hash table */ static struct hash_control *op_hash; @@ -77,8 +75,6 @@ const pseudo_typeS md_pseudo_table[] = {NULL, 0, 0}, }; -const int md_short_jump_size = 4; -const int md_long_jump_size = 4; const int md_reloc_size = 12; /* Size of relocation record */ /* This array holds the chars that always start a comment. If the @@ -719,7 +715,7 @@ sparc_ip (str) char *s; const char *args; char c; - struct sparc_opcode *insn; + const struct sparc_opcode *insn; char *argsStart; unsigned long opcode; unsigned int mask = 0; @@ -745,10 +741,10 @@ sparc_ip (str) break; default: - as_bad ("Unknown opcode: `%s'", str); - exit (1); + as_fatal ("Unknown opcode: `%s'", str); } - if ((insn = (struct sparc_opcode *) hash_find (op_hash, str)) == NULL) + insn = (struct sparc_opcode *) hash_find (op_hash, str); + if (insn == NULL) { as_bad ("Unknown opcode: `%s'", str); return; @@ -1544,23 +1540,6 @@ sparc_ip (str) case 'A': { -#ifdef NO_V9 - char *push = input_line_pointer; - expressionS e; - - input_line_pointer = s; - - expression (&e); - if (e.X_op == O_constant) - { - opcode |= e.X_add_number << 5; - s = input_line_pointer; - input_line_pointer = push; - continue; - } /* if absolute */ - - break; -#else int asi = 0; /* Parse an asi. */ @@ -1585,11 +1564,19 @@ sparc_ip (str) goto error; } } - else if (isdigit (*s)) + else { char *push = input_line_pointer; + expressionS e; input_line_pointer = s; - asi = get_absolute_expression (); + + expression (&e); + if (e.X_op != O_constant) + { + error_message = ": constant required for ASI"; + goto error; + } + asi = e.X_add_number; s = input_line_pointer; input_line_pointer = push; @@ -1599,14 +1586,8 @@ sparc_ip (str) goto error; } } - else - { - error_message = ": unrecognizable asi"; - goto error; - } opcode |= ASI (asi); continue; -#endif } /* alternate space */ case 'p': @@ -1718,7 +1699,8 @@ sparc_ip (str) { /* Args don't match. */ if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES - && !strcmp (insn->name, insn[1].name)) + && (insn->name == insn[1].name + || !strcmp (insn->name, insn[1].name))) { ++insn; s = argsStart; @@ -1895,9 +1877,18 @@ md_apply_fix (fixP, value) #ifdef OBJ_ELF /* FIXME: SPARC ELF relocations don't use an addend in the data field itself. This whole approach should be somehow combined - with the calls to bfd_perform_relocation. */ + with the calls to bfd_perform_relocation. Also, the value passed + in by fixup_segment includes the value of a defined symbol. We + don't want to include the value of an externally visible symbol. */ if (fixP->fx_addsy != NULL) - return 1; + { + if (S_IS_EXTERN (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))) + fixP->fx_addnumber -= S_GET_VALUE (fixP->fx_addsy); + return 1; + } #endif /* This is a hack. There should be a better way to @@ -2107,6 +2098,8 @@ tc_gen_reloc (section, fixp) case BFD_RELOC_32_PCREL_S2: case BFD_RELOC_SPARC13: case BFD_RELOC_SPARC_BASE13: + case BFD_RELOC_SPARC_WDISP16: + case BFD_RELOC_SPARC_WDISP19: case BFD_RELOC_SPARC_WDISP22: case BFD_RELOC_64: case BFD_RELOC_SPARC_10: @@ -2133,16 +2126,25 @@ tc_gen_reloc (section, fixp) assert (!fixp->fx_pcrel == !reloc->howto->pc_relative); /* @@ Why fx_addnumber sometimes and fx_offset other times? */ +#ifdef OBJ_AOUT + + if (reloc->howto->pc_relative == 0) + reloc->addend = fixp->fx_addnumber; + else + reloc->addend = fixp->fx_offset - reloc->address; + +#else /* elf or coff */ + if (reloc->howto->pc_relative == 0) reloc->addend = fixp->fx_addnumber; -#if defined (OBJ_ELF) || defined (OBJ_COFF) else if ((fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0) reloc->addend = (section->vma + fixp->fx_addnumber + md_pcrel_from (fixp)); -#endif else - reloc->addend = fixp->fx_offset - reloc->address; + reloc->addend = fixp->fx_offset; + +#endif return reloc; } @@ -2237,7 +2239,7 @@ print_insn (insn) */ #ifdef OBJ_ELF -CONST char *md_shortopts = "A:VQ:sq"; +CONST char *md_shortopts = "A:K:VQ:sq"; #else CONST char *md_shortopts = "A:"; #endif @@ -2314,6 +2316,15 @@ md_parse_option (c, arg) case 'q': /* quick -- native assembler does fewer checks */ break; + + case 'K': + if (strcmp (arg, "PIC") != 0) + as_warn ("Unrecognized option following -K"); + else + { + as_warn ("gas does not currently support PIC code for the SPARC"); + as_fatal ("use /usr/ccs/bin/as instead"); + } #endif default: @@ -2358,17 +2369,6 @@ md_undefined_symbol (name) return 0; } /* md_undefined_symbol() */ -/* Parse an operand that is machine-specific. - We just return without modifying the expression if we have nothing - to do. */ - -/* ARGSUSED */ -void -md_operand (expressionP) - expressionS *expressionP; -{ -} - /* Round up a section size to the appropriate boundary. */ valueT md_section_align (segment, size) @@ -2378,7 +2378,8 @@ md_section_align (segment, size) #ifndef OBJ_ELF /* This is not right for ELF; a.out wants it, and COFF will force the alignment anyways. */ - valueT align = (valueT) 1 << (valueT) (stdoutput->xvec->align_power_min); + valueT align = ((valueT) 1 + << (valueT) bfd_get_section_alignment (stdoutput, segment)); valueT newsize; /* turn alignment value into a mask */ align--; -- 2.34.1