* 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.
This commit is contained in:
Ian Lance Taylor 1995-07-05 21:52:10 +00:00
parent 9814e22f03
commit a7aa7a2ba9
4 changed files with 85 additions and 58 deletions

View file

@ -1,5 +1,15 @@
Wed Jul 5 12:01:49 1995 Ian Lance Taylor <ian@cygnus.com> Wed Jul 5 12:01:49 1995 Ian Lance Taylor <ian@cygnus.com>
* 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. * conf.in: Add undef of HAVE_SBRK.
* config/obj-coff.c (obj_coff_line): Call listing_source_line, in * config/obj-coff.c (obj_coff_line): Call listing_source_line, in

View file

@ -214,13 +214,22 @@ parse_args (pargc, pargv)
char *shortopts; char *shortopts;
extern CONST char *md_shortopts; extern CONST char *md_shortopts;
#ifdef VMS static const char std_shortopts[] =
/* -v takes an argument on VMS, so we don't make it a generic option. */ {
CONST char *std_shortopts = "-JKLRWZfa::DI:o:wX"; '-', 'J',
#else #ifndef WORKING_DOT_WORD
CONST char *std_shortopts = "-JKLRWZfa::DI:o:vwX"; /* -K is not meaningful if .word is not being hacked. */
'K',
#endif #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; struct option *longopts;
extern struct option md_longopts[]; extern struct option md_longopts[];
extern size_t md_longopts_size; extern size_t md_longopts_size;
@ -348,9 +357,11 @@ parse_args (pargc, pargv)
flag_signed_overflow_ok = 1; flag_signed_overflow_ok = 1;
break; break;
#ifndef WORKING_DOT_WORD
case 'K': case 'K':
flag_warn_displacement = 1; flag_warn_displacement = 1;
break; break;
#endif
case 'L': case 'L':
flag_keep_locals = 1; flag_keep_locals = 1;

View file

@ -473,7 +473,9 @@ COMMON fragS bss_address_frag;
COMMON unsigned char flag_no_comments; /* -f */ COMMON unsigned char flag_no_comments; /* -f */
COMMON unsigned char flag_debug; /* -D */ COMMON unsigned char flag_debug; /* -D */
COMMON unsigned char flag_signed_overflow_ok; /* -J */ COMMON unsigned char flag_signed_overflow_ok; /* -J */
#ifndef WORKING_DOT_WORD
COMMON unsigned char flag_warn_displacement; /* -K */ COMMON unsigned char flag_warn_displacement; /* -K */
#endif
/* True if local symbols should be retained. */ /* True if local symbols should be retained. */
COMMON unsigned char flag_keep_locals; /* -L */ 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 "tc.h"
#include "obj.h" #include "obj.h"
#ifdef USE_EMULATIONS
#include "emul.h"
#endif
#include "listing.h" #include "listing.h"
#ifndef LOCAL_LABELS_DOLLAR #ifndef LOCAL_LABELS_DOLLAR

View file

@ -38,8 +38,6 @@ static int warn_on_bump;
extern int target_big_endian; extern int target_big_endian;
const relax_typeS md_relax_table[1];
/* handle of the OPCODE hash table */ /* handle of the OPCODE hash table */
static struct hash_control *op_hash; static struct hash_control *op_hash;
@ -77,8 +75,6 @@ const pseudo_typeS md_pseudo_table[] =
{NULL, 0, 0}, {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 */ const int md_reloc_size = 12; /* Size of relocation record */
/* This array holds the chars that always start a comment. If the /* This array holds the chars that always start a comment. If the
@ -719,7 +715,7 @@ sparc_ip (str)
char *s; char *s;
const char *args; const char *args;
char c; char c;
struct sparc_opcode *insn; const struct sparc_opcode *insn;
char *argsStart; char *argsStart;
unsigned long opcode; unsigned long opcode;
unsigned int mask = 0; unsigned int mask = 0;
@ -745,10 +741,10 @@ sparc_ip (str)
break; break;
default: default:
as_bad ("Unknown opcode: `%s'", str); as_fatal ("Unknown opcode: `%s'", str);
exit (1);
} }
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); as_bad ("Unknown opcode: `%s'", str);
return; return;
@ -1544,23 +1540,6 @@ sparc_ip (str)
case 'A': 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; int asi = 0;
/* Parse an asi. */ /* Parse an asi. */
@ -1585,11 +1564,19 @@ sparc_ip (str)
goto error; goto error;
} }
} }
else if (isdigit (*s)) else
{ {
char *push = input_line_pointer; char *push = input_line_pointer;
expressionS e;
input_line_pointer = s; 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; s = input_line_pointer;
input_line_pointer = push; input_line_pointer = push;
@ -1599,14 +1586,8 @@ sparc_ip (str)
goto error; goto error;
} }
} }
else
{
error_message = ": unrecognizable asi";
goto error;
}
opcode |= ASI (asi); opcode |= ASI (asi);
continue; continue;
#endif
} /* alternate space */ } /* alternate space */
case 'p': case 'p':
@ -1718,7 +1699,8 @@ sparc_ip (str)
{ {
/* Args don't match. */ /* Args don't match. */
if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES 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; ++insn;
s = argsStart; s = argsStart;
@ -1895,9 +1877,18 @@ md_apply_fix (fixP, value)
#ifdef OBJ_ELF #ifdef OBJ_ELF
/* FIXME: SPARC ELF relocations don't use an addend in the data /* FIXME: SPARC ELF relocations don't use an addend in the data
field itself. This whole approach should be somehow combined 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) 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 #endif
/* This is a hack. There should be a better way to /* 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_32_PCREL_S2:
case BFD_RELOC_SPARC13: case BFD_RELOC_SPARC13:
case BFD_RELOC_SPARC_BASE13: case BFD_RELOC_SPARC_BASE13:
case BFD_RELOC_SPARC_WDISP16:
case BFD_RELOC_SPARC_WDISP19:
case BFD_RELOC_SPARC_WDISP22: case BFD_RELOC_SPARC_WDISP22:
case BFD_RELOC_64: case BFD_RELOC_64:
case BFD_RELOC_SPARC_10: case BFD_RELOC_SPARC_10:
@ -2133,16 +2126,25 @@ tc_gen_reloc (section, fixp)
assert (!fixp->fx_pcrel == !reloc->howto->pc_relative); assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
/* @@ Why fx_addnumber sometimes and fx_offset other times? */ /* @@ 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) if (reloc->howto->pc_relative == 0)
reloc->addend = fixp->fx_addnumber; reloc->addend = fixp->fx_addnumber;
#if defined (OBJ_ELF) || defined (OBJ_COFF)
else if ((fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0) else if ((fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
reloc->addend = (section->vma reloc->addend = (section->vma
+ fixp->fx_addnumber + fixp->fx_addnumber
+ md_pcrel_from (fixp)); + md_pcrel_from (fixp));
#endif
else else
reloc->addend = fixp->fx_offset - reloc->address; reloc->addend = fixp->fx_offset;
#endif
return reloc; return reloc;
} }
@ -2237,7 +2239,7 @@ print_insn (insn)
*/ */
#ifdef OBJ_ELF #ifdef OBJ_ELF
CONST char *md_shortopts = "A:VQ:sq"; CONST char *md_shortopts = "A:K:VQ:sq";
#else #else
CONST char *md_shortopts = "A:"; CONST char *md_shortopts = "A:";
#endif #endif
@ -2314,6 +2316,15 @@ md_parse_option (c, arg)
case 'q': case 'q':
/* quick -- native assembler does fewer checks */ /* quick -- native assembler does fewer checks */
break; 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 #endif
default: default:
@ -2358,17 +2369,6 @@ md_undefined_symbol (name)
return 0; return 0;
} /* md_undefined_symbol() */ } /* 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. */ /* Round up a section size to the appropriate boundary. */
valueT valueT
md_section_align (segment, size) md_section_align (segment, size)
@ -2378,7 +2378,8 @@ md_section_align (segment, size)
#ifndef OBJ_ELF #ifndef OBJ_ELF
/* This is not right for ELF; a.out wants it, and COFF will force /* This is not right for ELF; a.out wants it, and COFF will force
the alignment anyways. */ 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; valueT newsize;
/* turn alignment value into a mask */ /* turn alignment value into a mask */
align--; align--;