aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog10
-rw-r--r--gas/as.c23
-rw-r--r--gas/as.h5
-rw-r--r--gas/config/tc-sparc.c105
4 files changed, 85 insertions, 58 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 57a1426..121d05d 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,15 @@
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.
* config/obj-coff.c (obj_coff_line): Call listing_source_line, in
diff --git a/gas/as.c b/gas/as.c
index 5a937b3..d439a95 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 7477388..252106c 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 5fa7d9d..5bfa901 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--;