instead, call md_show_usage.
(parse_args): Use getopt_long_only. Take pointers to argc and
argv.
(main): Pass parse_args pointers.
* as.h: Remove 3 variables that are redundant with flagseen.
* as.c, messages.c: Change their users to use flagseen.
Define getopt stuff.
* tc.h: Update md_parse_option decl. Add md_show_usage decl.
* config/tc-*.c: Add md_shortopts, md_longopts,
md_longopts_size, md_show_usage. Change calling convention for
md_parse_option. Remove md_parse_long_option.
* config/tc-ns32k.c: Rename `struct option' to `struct ns32k_option'.
* config/tc-i386.h: Don't define md_parse_option.
+Fri Jun 3 12:50:13 1994 David J. MacKenzie (djm@rtl.cygnus.com)
+
+ * as.c (show_usage): Remove target specific messages;
+ instead, call md_show_usage.
+ (parse_args): Use getopt_long_only. Take pointers to argc and
+ argv.
+ (main): Pass parse_args pointers.
+ * as.h: Remove 3 variables that are redundant with flagseen.
+ * as.c, messages.c: Change their users to use flagseen.
+ Define getopt stuff.
+ * tc.h: Update md_parse_option decl. Add md_show_usage decl.
+ * config/tc-*.c: Add md_shortopts, md_longopts,
+ md_longopts_size, md_show_usage. Change calling convention for
+ md_parse_option. Remove md_parse_long_option.
+ * config/tc-ns32k.c: Rename `struct option' to `struct ns32k_option'.
+ * config/tc-i386.h: Don't define md_parse_option.
+
Thu Jun 2 13:54:46 1994 David J. Mackenzie (djm@rtl.cygnus.com)
* as.c (show_usage): New function.
-K warn when differences altered for long displacements\n\
-L keep local symbols (starting with `L')\n");
fprintf (stream, "\
--o OBJFILE name the object-file output OBJFILE [default a.out]\n\
+-o OBJFILE name the object-file output OBJFILE (default a.out)\n\
-R fold data section into text section\n\
--statistics print maximum bytes and total seconds used\n\
--v, -version print assembler version number\n\
+-v print assembler version number\n\
--version print assembler version number and exit\n\
-W suppress warnings\n\
-w ignored\n\
-x ignored\n\
-Z generate object file even after errors\n");
-#ifdef TC_ALPHA
- fprintf(stream, "\
-ALPHA options:\n\
--32addr treat addresses as 32-bit values\n\
--F lack floating point instructions support\n\
--nocpp ignored\n");
-#endif
-
-#ifdef TC_I960
- fprintf(stream, "\
-I960 options:\n\
--ACA | -ACA_A | -ACB | -ACC | -AKA | -AKB | -AKC | -AMC\n\
- specify variant of 960 architecture\n\
--b add code to collect statistics about branches taken\n\
--linkrelax make relocatable instructions undefined (?)\n\
--norelax don't alter compare-and-branch instructions for\n\
- long displacements\n");
-#endif
-
-#ifdef TC_M68K
- fprintf(stream, "\
-680X0 options:\n\
--l use 1 word for refs to undefined symbols [default 2]\n\
--m68000 | -m68008 | -m68010 | -m68020 | -m68030 | -m68040\n\
- | -m68302 | -m68331 | -m68332 | -m68333 | -m68340 | -mcpu32\n\
- specify variant of 680X0 architecture [default 68020]\n\
--m68881 | -m68882 | -mno-68881 | -mno-68882\n\
- target has/lacks floating-point coprocessor\n\
- [default yes for 68020, 68030, and cpu32]\n\
--m68851 | -mno-68851\n\
- target has/lacks memory-management unit coprocessor\n\
- [default yes for 68020 and up]\n\
--pic, -k (sun3) generate position independent code\n\
--S turn jbsr into jsr\n\
---register-prefix-optional\n\
- recognize register names without prefix character\n");
-#endif
-
-#ifdef TC_MIPS
- fprintf(stream, "\
-MIPS options:\n\
--membedded-pic generate embedded position independent code\n\
--nocpp ignored\n\
--EB generate big endian output\n\
--EL generate little endian output\n\
--g, -g2 do not remove uneeded NOPs or swap branches\n\
--G NUM allow referencing objects up to NUM bytes\n\
- implicitly with the gp register [default 8]\n\
--mips1, -mcpu=r{2,3}000 generate code for r2000 and r3000\n\
--mips2, -mcpu=r6000 generate code for r6000\n\
--mips3, -mcpu=r4000 generate code for r4000\n\
--O0 remove unneeded NOPs, do not swap branches\n\
--O remove unneeded NOPs and swap branches\n\
---trap, --no-break trap exception on div by 0 and mult overflow\n\
---break, --no-trap break exception on div by 0 and mult overflow\n");
-#ifdef OBJ_ELF
- fprintf(stream, "\
-MIPS ELF options:\n\
--KPIC, -call_shared generate SVR4 position independent code\n\
--non_shared do not generate position independent code\n");
-#endif
-#endif
-
-#ifdef TC_NS32K
- fprintf(stream, "\
-NS32K options:\n\
--m32032 | -m32532 select variant of NS32K architecture\n");
-#endif
-
-#ifdef TC_PPC
- fprintf(stream, "\
-PowerPC options:\n\
--u ignored\n\
--mpwrx generate code for IBM POWER/2 (RIOS2)\n\
--mpwr generate code for IBM POWER (RIOS1)\n\
--m601 generate code for Motorola PowerPC 601\n\
--mppc generate code for Motorola PowerPC 603/604\n\
--many generate code for any architecture (PWR/PWRX/PPC)\n");
-#ifdef OBJ_ELF
- fprintf(stream, "\
-PowerPC ELF options:\n\
--V print assembler version number\n\
--Qy, -Qn ignored\n");
-#endif
-#endif
-
-#ifdef TC_SH
- fprintf(stream, "\
-SH options:\n\
--relax alter jump instructions for long displacements\n");
-#endif
-
-#ifdef TC_SPARC
- fprintf(stream, "\
-SPARC options:\n\
--Av6 | -Av7 | -Av8 | -Asparclite\n\
- specify variant of SPARC architecture\n\
--bump warn when assembler switches architectures\n\
--sparc ignored\n");
-#ifdef OBJ_ELF
- fprintf(stream, "\
-SPARC ELF options:\n\
--V print assembler version number\n\
--q ignored\n\
--Qy, -Qn ignored\n\
--s ignored\n");
-#endif
-#endif
-
-#ifdef TC_TAHOE
- fprintf(stream, "\
-Tahoe options:\n\
--a ignored\n\
--d LENGTH ignored\n\
--J ignored\n\
--S ignored\n\
--t FILE ignored\n\
--T ignored\n\
--V ignored\n");
-#endif
-
-#ifdef TC_VAX
- fprintf(stream, "\
-VAX options:\n\
--d LENGTH ignored\n\
--J ignored\n\
--S ignored\n\
--t FILE ignored\n\
--T ignored\n\
--V ignored\n");
-#endif
-
-#ifdef TC_Z8K
- fprintf(stream, "\
-Z8K options:\n\
--z8001 generate segmented code\n\
--z8002 generate unsegmented code\n");
-#endif
+ md_show_usage (stream);
}
/*
* After we have munged argv[], the only things left are source file
* name(s) and ""(s) denoting stdin. These file names are used
* (perhaps more than once) later.
- */
-/* FIXME-SOMEDAY this should use getopt. */
-/*
+ *
* check for new machine-dep cmdline options in
* md_parse_option definitions in config/tc-*.c
*/
void
-parse_args (argc, argv)
- int argc;
- char **argv;
+parse_args (pargc, pargv)
+ int *pargc;
+ char ***pargv;
{
- char *arg; /* an arg to program */
- char a; /* an arg flag (after -) */
-
- argc--; /* don't count argv[0] */
- argv++; /* skip argv[0] */
-
- for (; argc--; argv++)
+ int old_argc, new_argc;
+ char **old_argv, **new_argv;
+
+ /* Starting the short option string with '-' is for programs that
+ expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1. */
+
+ char *shortopts;
+ extern CONST char *md_shortopts;
+ CONST char *std_shortopts = "-1JKLRWZfa::DI:o:vwX";
+
+ struct option *longopts;
+ extern struct option md_longopts[];
+ extern size_t md_longopts_size;
+ static struct option std_longopts[] = {
+#define OPTION_HELP (OPTION_STD_BASE)
+ {"help", no_argument, NULL, OPTION_HELP},
+#define OPTION_NOCPP (OPTION_STD_BASE + 1)
+ {"nocpp", no_argument, NULL, OPTION_NOCPP},
+#define OPTION_STATISTICS (OPTION_STD_BASE + 2)
+ {"statistics", no_argument, NULL, OPTION_STATISTICS},
+#define OPTION_VERSION (OPTION_STD_BASE + 3)
+ {"version", no_argument, NULL, OPTION_VERSION},
+ };
+
+ /* Construct the option lists from the standard list and the
+ target dependent list. */
+ shortopts = concat (std_shortopts, md_shortopts, (char *) NULL);
+ longopts = xmalloc (sizeof (std_longopts) + md_longopts_size);
+ memcpy (longopts, std_longopts, sizeof (std_longopts));
+ memcpy ((char *) longopts + sizeof (std_longopts),
+ md_longopts, md_longopts_size);
+
+ /* Make a local copy of the old argv. */
+ old_argc = *pargc;
+ old_argv = *pargv;
+
+ /* Initialize a new argv that contains no options. */
+ new_argv = (char **) xmalloc (sizeof (char *) * (old_argc + 1));
+ new_argv[0] = old_argv[0];
+ new_argc = 1;
+ new_argv[new_argc] = NULL;
+
+ while (1)
{
- arg = *argv; /* argv points to this argument */
-
- if (*arg != '-') /* Filename. We need it later. */
- continue; /* Keep scanning args looking for flags. */
- /* Handle double-dash options. */
- if (arg[1] == '-')
- {
- if (arg[2] == 0)
- {
- /* "--" as an argument means read stdin. */
- /* On this scan, we don't want to think about filenames. */
- *argv = ""; /* A code that means 'use stdin'. */
- }
- else if (strcmp (arg, "--statistics") == 0)
- {
- statistics_flag = 1;
- *argv = NULL;
- }
- else if (strcmp (arg, "--help") == 0)
- {
- show_usage (stdout);
- exit (0);
- }
- else if (strcmp (arg, "--version") == 0)
- {
- print_version_id ();
- exit (0);
- }
-#ifdef md_parse_long_option
- else if (md_parse_long_option (arg))
- *argv = NULL;
-#endif
- else
- {
- as_warn ("Unknown option `%s' ignored", arg);
- *argv = NULL;
- }
- continue;
- }
+ /* getopt_long_only is like getopt_long, but '-' as well as '--' can
+ indicate a long option. */
+ int longind;
+ int optc = getopt_long_only (old_argc, old_argv, shortopts, longopts,
+ &longind);
- /* This better be a switch. */
- arg++; /*->letter. */
+ if (optc == -1)
+ break;
- while ((a = *arg) != '\0')
- { /* scan all the 1-char flags */
- arg++; /* arg->after letter. */
- a &= 0x7F; /* ascii only please */
- flagseen[(unsigned char) a] = 1;
- switch (a)
+ switch (optc)
+ {
+ default:
+ /* md_parse_option should return 1 if it recognizes optc,
+ 0 if not. */
+ if (md_parse_option (optc, optarg) == 0)
+ exit (EXIT_FAILURE);
+ break;
+
+ case '?':
+ exit (EXIT_FAILURE);
+
+ case 1: /* File name. */
+ if (!strcmp (optarg, "-"))
+ optarg = "";
+ new_argv[new_argc++] = optarg;
+ new_argv[new_argc] = NULL;
+ break;
+
+ case OPTION_HELP:
+ show_usage (stdout);
+ exit (0);
+
+ case OPTION_NOCPP:
+ break;
+
+ case OPTION_STATISTICS:
+ statistics_flag = 1;
+ break;
+
+ case OPTION_VERSION:
+ print_version_id ();
+ exit (0);
+
+ case '1':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'R':
+ case 'W':
+ case 'Z':
+ case 'f':
+ flagseen[(unsigned char) optc] = 1;
+ break;
+
+ case 'a':
+ if (optarg)
{
- case 'a':
- {
- int loop = 1;
-
- while (loop)
- {
- switch (*arg)
- {
- case 'l':
- listing |= LISTING_LISTING;
- arg++;
- break;
- case 's':
- listing |= LISTING_SYMBOLS;
- arg++;
- break;
- case 'h':
- listing |= LISTING_HLL;
- arg++;
- break;
-
- case 'n':
- listing |= LISTING_NOFORM;
- arg++;
- break;
- case 'd':
- listing |= LISTING_NODEBUG;
- arg++;
- break;
- default:
- if (!listing)
- listing = LISTING_DEFAULT;
- loop = 0;
- break;
- }
- }
- }
-
- break;
-
-
- case 'f':
- break; /* -f means fast - no need for "app" preprocessor. */
-
- case 'D':
- /* DEBUG is implemented: it debugs different */
- /* things to other people's assemblers. */
- break;
-
- case 'I':
- { /* Include file directory */
-
- char *temp = NULL;
- if (*arg)
- {
- temp = strdup (arg);
- if (!temp)
- as_fatal ("virtual memory exhausted");
- }
- else if (argc)
- {
- *argv = NULL;
- argc--;
- temp = *++argv;
- }
- else
- as_warn ("%s: I expected a filename after -I", myname);
- add_include_dir (temp);
- arg = ""; /* Finished with this arg. */
- break;
- }
-
-#ifdef WARN_SIGNED_OVERFLOW_WORD
- /* Don't warn about signed overflow. */
- case 'J':
- break;
-#endif
-
-#ifndef WORKING_DOT_WORD
- case 'K':
- break;
-#endif
-
- case 'L': /* -L means keep L* symbols */
- break;
-
- case 'o':
- if (*arg) /* Rest of argument is object file-name. */
+ while (*optarg)
{
- out_file_name = strdup (arg);
- if (!out_file_name)
- as_fatal ("virtual memory exhausted");
+ switch (*optarg)
+ {
+ case 'd':
+ listing |= LISTING_NODEBUG;
+ break;
+ case 'h':
+ listing |= LISTING_HLL;
+ break;
+ case 'l':
+ listing |= LISTING_LISTING;
+ break;
+ case 'n':
+ listing |= LISTING_NOFORM;
+ break;
+ case 's':
+ listing |= LISTING_SYMBOLS;
+ break;
+ default:
+ as_bad ("invalid listing option `%c'", *optarg);
+ exit (EXIT_FAILURE);
+ break;
+ }
+ optarg++;
}
- else if (argc)
- { /* Want next arg for a file-name. */
- *argv = NULL; /* This is not a file-name. */
- argc--;
- out_file_name = *++argv;
- }
- else
- as_warn ("%s: I expected a filename after -o. \"%s\" assumed.",
- myname, out_file_name);
- arg = ""; /* Finished with this arg. */
- break;
-
- case 'n':
- if (*arg && strcmp(arg, "ocpp") == 0)
- ;
- else
- {
- as_warn ("Unknown option `-n%s' ignored", arg);
- arg += strlen (arg);
- break;
- }
-
- case 'R':
- /* -R means put data into text segment */
- flag_readonly_data_in_text = 1;
- break;
-
- case 'v':
-#ifdef VMS
- {
- extern char *compiler_version_string;
- compiler_version_string = arg;
- }
-#else /* not VMS */
- if (*arg && strcmp (arg, "ersion"))
- {
- as_warn ("Unknown option `-v%s' ignored", arg);
- arg += strlen (arg);
- break;
- }
-
- print_version_id ();
-#endif /* not VMS */
- while (*arg)
- arg++; /* Skip the rest */
- break;
-
- case 'W':
- /* -W means don't warn about things */
- flag_suppress_warnings = 1;
- break;
-
- case 'w':
- case 'X':
- /* -X means treat warnings as errors */
- break;
- case 'Z':
- /* -Z means attempt to generate object file even after errors. */
- flag_always_generate_output = 1;
- break;
-
- default:
- --arg;
- if (md_parse_option (&arg, &argc, &argv) == 0)
- as_warn ("%s: I don't understand '%c' flag.", myname, a);
- if (arg && *arg)
- arg++;
- break;
}
+ if (!listing)
+ listing = LISTING_DEFAULT;
+ break;
+
+ case 'D':
+ /* DEBUG is implemented: it debugs different */
+ /* things to other people's assemblers. */
+ break;
+
+ case 'I':
+ { /* Include file directory */
+ char *temp = strdup (optarg);
+ if (!temp)
+ as_fatal ("virtual memory exhausted");
+ add_include_dir (temp);
+ break;
+ }
+
+ case 'o':
+ out_file_name = strdup (optarg);
+ if (!out_file_name)
+ as_fatal ("virtual memory exhausted");
+ break;
+
+ case 'v':
+ print_version_id ();
+ break;
+
+ case 'w':
+ break;
+
+ case 'X':
+ /* -X means treat warnings as errors */
+ break;
}
- /*
- * We have just processed a "-..." arg, which was not a
- * file-name. Smash it so the
- * things that look for filenames won't ever see it.
- *
- * Whatever argv points to, it has already been used
- * as part of a flag, so DON'T re-use it as a filename.
- */
- *argv = NULL; /* NULL means 'not a file-name' */
}
+
+ free (shortopts);
+ free (longopts);
+
+ *pargc = new_argc;
+ *pargv = new_argv;
}
int
read_begin ();
input_scrub_begin ();
frag_init ();
- parse_args (argc, argv);
+ parse_args (&argc, &argv);
#ifdef BFD_ASSEMBLER
output_file_create (out_file_name);
#endif
if (seen_at_least_1_file ()
- && !((had_warnings () && flag_always_generate_output)
+ && !((had_warnings () && flagseen['Z'])
|| had_errors () > 0))
keep_it = 1;
else
#include "config.h"
#include <stdio.h>
+#include <getopt.h>
+/* The first getopt value for machine-independent long options.
+ 150 isn't special; it's just an arbitrary non-ASCII char value. */
+#define OPTION_STD_BASE 150
+/* The first getopt value for machine-dependent long options.
+ 170 gives the standard options room to grow. */
+#define OPTION_MD_BASE 170
+
#ifdef DEBUG
#undef NDEBUG
#endif
/* ['x'] TRUE if "-x" seen. */
COMMON char flagseen[128];
-COMMON unsigned char flag_readonly_data_in_text;
-COMMON unsigned char flag_suppress_warnings;
-COMMON unsigned char flag_always_generate_output;
/* name of emitted object file */
COMMON char *out_file_name;
}
#endif /* OBJ_AOUT */
+\f
+CONST char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
int
-md_parse_option (argP, cntP, vecP)
- char **argP;
- int *cntP;
- char ***vecP;
+md_parse_option (c, arg)
+ int c;
+ char *arg;
{
return 0;
}
-
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+}
+\f
/* Default the values of symbols known that should be "predefined". We
don't bother to predefine them unless you actually use one, since there
are a lot of them. */
while (--nb);
}
}
+\f
+CONST char *md_shortopts = "Fm:";
+struct option md_longopts[] = {
+#define OPTION_32ADDR (OPTION_MD_BASE)
+ {"32addr", no_argument, NULL, OPTION_32ADDR},
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
int
-md_parse_option (argP, cntP, vecP)
- char **argP;
- int *cntP;
- char ***vecP;
+md_parse_option (c, arg)
+ int c;
+ char *arg;
{
- if (**argP == 'F')
+ switch (c)
{
+ case 'F':
nofloats = 1;
- return 1;
- }
-#if 0 /* I have no idea if this stuff would work any more. And it's
- probably not right for ECOFF anyways. */
- /* Use base-register addressing, e.g. PIC code */
- if (**argP == 'B')
- {
- if (first_32bit_quadrant)
- {
- first_32bit_quadrant = 0;
- base_register = GP;
- }
- else
- {
- first_32bit_quadrant = 1;
- base_register = ZERO;
- }
- if (argP[0][1] == 'k')
- no_mixed_code = 1;
- argP[0][1] = 0;
- return 1;
- }
-#endif
- if (!strcmp (*argP, "32addr"))
- {
+ break;
+
+ case OPTION_32ADDR:
addr32 = 1;
- *argP += 6;
- return 1;
- }
- if (!strcmp (*argP, "nocpp"))
- {
- *argP += 5;
- return 1;
- }
- if (**argP == 'm')
- {
- unsigned long mach;
-
- (*argP)++;
- if (!strcmp (*argP, "21064"))
- mach = 21064;
- else if (!strcmp (*argP, "21066"))
- mach = 21066;
- else if (!strcmp (*argP, "21164"))
- mach = 21164;
- else
- {
- mach = 0;
- (*argP)--;
- return 0;
- }
- (*argP) += 5;
+ break;
- if (machine != 0 && machine != mach)
- {
- as_warn ("machine type %lu already chosen, overriding with %lu",
- machine, mach);
- }
- machine = mach;
+ case 'm':
+ {
+ unsigned long mach;
+
+ if (!strcmp (arg, "21064"))
+ mach = 21064;
+ else if (!strcmp (arg, "21066"))
+ mach = 21066;
+ else if (!strcmp (arg, "21164"))
+ mach = 21164;
+ else
+ {
+ as_bad ("invalid architecture %s", arg);
+ return 0;
+ }
- return 1;
+ if (machine != 0 && machine != mach)
+ {
+ as_warn ("machine type %lu already chosen, overriding with %lu",
+ machine, mach);
+ }
+ machine = mach;
+ }
+ break;
+
+ default:
+ return 0;
}
- return 0;
+
+ return 1;
}
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, "\
+Alpha options:\n\
+-32addr treat addresses as 32-bit values\n\
+-F lack floating point instructions support\n\
+-m21064 | -m21066 | -m21164\n\
+ specify variant of Alpha architecture\n\
+-nocpp ignored\n");
+}
+\f
static void
s_proc (is_static)
{
}
return 0;
}
+\f
+CONST char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
int
-md_parse_option (argP, cntP, vecP)
- char **argP;
- int *cntP;
- char ***vecP;
-
+md_parse_option (c, arg)
+ int c;
+ char *arg;
{
return 0;
}
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+}
+\f
int md_short_jump_size;
void
if (flagseen['R'])
{
as_warn ("-R option not supported on this target.");
- flag_readonly_data_in_text = 0;
flagseen['R'] = 0;
}
return size;
}
+\f
+CONST char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
-/* Parse machine dependent options. There are none on the PA. */
int
-md_parse_option (argP, cntP, vecP)
- char **argP;
- int *cntP;
- char ***vecP;
+md_parse_option (c, arg)
+ int c;
+ char *arg;
{
- return 1;
+ return 0;
}
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+}
+\f
/* We have no need to default values of symbols. */
symbolS *
first line of the input file. This is because the compiler outputs
#NO_APP at the beginning of its output. */
/* Also note that comments started like this one will always work if
- '/' isn't otherwise defined. */
+ '/' isn't otherwise defined. */
#if defined (TE_I386AIX) || defined (OBJ_ELF)
const char line_comment_chars[] = "";
#else
smallest_imm_type (num)
long num;
{
- return ((num == 1)
- ? (Imm1 | Imm8 | Imm8S | Imm16 | Imm32)
- : fits_in_signed_byte (num)
+#if 0
+ /* This code is disabled because all the Imm1 forms in the opcode table
+ are slower on the i486, and they're the versions with the implicitly
+ specified single-position displacement, which has another syntax if
+ you really want to use that form. If you really prefer to have the
+ one-byte-shorter Imm1 form despite these problems, re-enable this
+ code. */
+ if (num == 1)
+ return Imm1 | Imm8 | Imm8S | Imm16 | Imm32;
+#endif
+ return (fits_in_signed_byte (num)
? (Imm8S | Imm8 | Imm16 | Imm32)
: fits_in_unsigned_byte (num)
? (Imm8 | Imm16 | Imm32)
{"value", cons, 2},
{"noopt", s_ignore, 0},
{"optim", s_ignore, 0},
-#ifdef OBJ_ELF
- {"zero", s_space, 0},
-#endif
{0, 0, 0}
};
struct obstack o;
/* hash table for opcode lookup */
-static struct hash_control *op_hash = (struct hash_control *) 0;
+static struct hash_control *op_hash;
/* hash table for register lookup */
-static struct hash_control *reg_hash = (struct hash_control *) 0;
+static struct hash_control *reg_hash;
/* hash table for prefix lookup */
-static struct hash_control *prefix_hash = (struct hash_control *) 0;
+static struct hash_control *prefix_hash;
\f
void
obstack_begin (&o, 4096);
/* initialize op_hash hash table */
- op_hash = hash_new (); /* xmalloc handles error */
+ op_hash = hash_new ();
{
register const template *optab;
record_alignment (bss_section, 2);
#endif
}
-
-void
-md_end ()
-{
-} /* not much to do here. */
\f
#ifdef DEBUG386
We assume that the scrubber has arranged it so that line[0] is the valid
start of a (possibly prefixed) opcode. */
{
- register char *l = line; /* Fast place to put LINE. */
+ char *l = line;
/* 1 if operand is pending after ','. */
unsigned int expecting_operand = 0;
l++;
}
else
- { /* this opcode's got a prefix */
- register unsigned int q;
- register prefix_entry *prefix;
+ {
+ /* This opcode's got a prefix. */
+ unsigned int q;
+ prefix_entry *prefix;
if (l == token_start)
{
t < current_templates->end;
t++)
{
-
/* must have right number of operands */
if (i.operands != t->operands)
continue;
}
/* Copy the template we found (we may change it!). */
- memcpy (&i.tm, t, sizeof (template));
+ i.tm = *t;
t = &i.tm; /* alter new copy of template */
/* If there's no opcode suffix we try to invent one based on register
pi (line, &i);
}
#endif /* DEBUG386 */
-
}
- return;
}
\f
/* Parse OPERAND_STRING into the i386_insn structure I. Returns non-zero
valueT value; /* The value of the bits. */
int nbytes; /* Number of bytes in the output. */
{
- register char *p = con;
-
- switch (nbytes)
- {
- case 1:
- p[0] = value & 0xff;
- break;
- case 2:
- p[0] = value & 0xff;
- p[1] = (value >> 8) & 0xff;
- break;
- case 4:
- p[0] = value & 0xff;
- p[1] = (value >> 8) & 0xff;
- p[2] = (value >> 16) & 0xff;
- p[3] = (value >> 24) & 0xff;
- break;
- default:
- BAD_CASE (nbytes);
- }
+ number_to_chars_littleendian (con, value, nbytes);
}
{
register char *p = fixP->fx_where + fixP->fx_frag->fr_literal;
-#ifdef BFD_ASSEMBLER
+#if defined (BFD_ASSEMBLER) && !defined (TE_Mach)
/*
* This is a hack. There should be a better way to
* handle this.
if (fixP->fx_r_type == BFD_RELOC_32_PCREL && fixP->fx_addsy)
{
value += fixP->fx_where + fixP->fx_frag->fr_address;
- }
+#ifdef OBJ_ELF
+ if (S_GET_SEGMENT (fixP->fx_addsy) != undefined_section)
+ {
+ /* Yes, we add the values in twice. This is because
+ bfd_perform_relocation subtracts them out again. I think
+ bfd_perform_relocation is broken, but I don't dare change
+ it. FIXME. */
+ value += fixP->fx_where + fixP->fx_frag->fr_address;
+ }
#endif
-
- switch (fixP->fx_size)
- {
- case 1:
- *p = value;
- break;
- case 2:
- *p++ = value;
- *p = (value >> 8);
- break;
- case 4:
- *p++ = value;
- *p++ = (value >> 8);
- *p++ = (value >> 16);
- *p = (value >> 24);
- break;
- default:
- BAD_CASE (fixP->fx_size);
}
+#endif
+ md_number_to_chars (p, value, fixP->fx_size);
}
#ifdef BFD_ASSEMBLER
*p = '\0';
return (reg_entry *) hash_find (reg_hash, reg_name_given);
}
+\f
+CONST char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ return 0;
+}
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+}
+\f
/* We have no need to default values of symbols. */
/* ARGSUSED */
#include "opcode/i960.h"
+extern char *strchr ();
+
extern char *input_line_pointer;
extern struct hash_control *po_hash;
extern char *next_object_file_charP;
+#if !defined (BFD_ASSEMBLER) && !defined (BFD)
#ifdef OBJ_COFF
const int md_reloc_size = sizeof (struct reloc);
#else /* OBJ_COFF */
const int md_reloc_size = sizeof (struct relocation_info);
#endif /* OBJ_COFF */
+#endif
/***************************
* Local i80960 routines *
const struct i960_opcode *oP; /* Pointer into opcode table */
const char *retval; /* Value returned by hash functions */
- if (((op_hash = hash_new ()) == 0)
- || ((reg_hash = hash_new ()) == 0)
- || ((areg_hash = hash_new ()) == 0))
- as_fatal ("virtual memory exceeded");
+ op_hash = hash_new ();
+ reg_hash = hash_new ();
+ areg_hash = hash_new ();
/* For some reason, the base assembler uses an empty string for "no
error message", instead of a NULL pointer. */
- retval = "";
+ retval = 0;
for (oP = i960_opcodes; oP->name && !retval; oP++)
retval = hash_insert (op_hash, oP->name, (PTR) oP);
}
/*****************************************************************************
- * md_end: One-time final cleanup
- *
- * None necessary
- *
- **************************************************************************** */
-void
-md_end ()
-{
-}
-
-/*****************************************************************************
* md_assemble: Assemble an instruction
*
* Assumptions about the passed-in text:
{
as_warn (bp_error_msg);
}
- /* Output opcode & set up "fixup" (relocation);
- * flag relocation as 'callj' type.
- */
+ /* Output opcode & set up "fixup" (relocation); flag
+ relocation as 'callj' type. */
know (oP->num_ops == 1);
get_cdisp (args[1], "CTRL", oP->opcode, 24, 0, 1);
break;
**************************************************************************** */
void
md_number_to_chars (buf, value, n)
- char *buf; /* Put output here */
- valueT value; /* The integer to be converted */
- int n; /* Number of bytes to output (significant bytes
- * in 'value')
- */
+ char *buf;
+ valueT value;
+ int n;
{
- while (n--)
- {
- *buf++ = value;
- value >>= 8;
- }
-
- /* XXX line number probably botched for this warning message. */
- if (value != 0 && value != -1)
- {
- as_bad ("Displacement too long for instruction field length.");
- }
-
- return;
-} /* md_number_to_chars() */
+ number_to_chars_littleendian (buf, value, n);
+}
/*****************************************************************************
* md_chars_to_number: convert from target byte order to host byte order.
*sizeP = prec * LNUM_SIZE;
/* Output the LITTLENUMs in REVERSE order in accord with i80960
- * word-order. (Dunno why atof_ieee doesn't do it in the right
- * order in the first place -- probably because it's a hack of
- * atof_m68k.)
- */
+ word-order. (Dunno why atof_ieee doesn't do it in the right
+ order in the first place -- probably because it's a hack of
+ atof_m68k.) */
for (wordP = words + prec - 1; prec--;)
{
litP += sizeof (LITTLENUM_TYPE);
}
- return ""; /* Someone should teach Dean about null pointers */
+ return 0;
}
}
} /* md_number_to_field() */
-
+\f
/*****************************************************************************
* md_parse_option
* Invocation line includes a switch not recognized by the base assembler.
* that is supported by SOME version of the 960 (even if this
* means mixing architectures!).
*
- **************************************************************************** */
+ *****************************************************************************/
+
+CONST char *md_shortopts = "A:b";
+struct option md_longopts[] = {
+#define OPTION_LINKRELAX (OPTION_MD_BASE)
+ {"linkrelax", no_argument, NULL, OPTION_LINKRELAX},
+#define OPTION_NORELAX (OPTION_MD_BASE + 1)
+ {"norelax", no_argument, NULL, OPTION_NORELAX},
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
int
-md_parse_option (argP, cntP, vecP)
- char **argP;
- int *cntP;
- char ***vecP;
+md_parse_option (c, arg)
+ int c;
+ char *arg;
{
- char *p;
struct tabentry
{
char *flag;
{ "CA", ARCH_CA },
{ NULL, 0 }
};
- struct tabentry *tp;
- if (!strcmp (*argP, "linkrelax"))
+
+ switch (c)
{
+ case OPTION_LINKRELAX:
linkrelax = 1;
flagseen['L'] = 1;
- }
- else if (!strcmp (*argP, "norelax"))
- {
+ break;
+
+ case OPTION_NORELAX:
norelax = 1;
+ break;
- }
- else if (**argP == 'b')
- {
+ case 'b':
instrument_branches = 1;
+ break;
- }
- else if (**argP == 'A')
- {
- p = (*argP) + 1;
-
- for (tp = arch_tab; tp->flag != NULL; tp++)
- {
- if (!strcmp (p, tp->flag))
- {
- break;
- }
- }
+ case 'A':
+ {
+ struct tabentry *tp;
+ char *p = arg;
+
+ for (tp = arch_tab; tp->flag != NULL; tp++)
+ {
+ if (!strcmp (p, tp->flag))
+ {
+ break;
+ }
+ }
+
+ if (tp->flag == NULL)
+ {
+ as_bad ("invalid architecture %s", p);
+ return 0;
+ }
+ else
+ {
+ architecture = tp->arch;
+ }
+ }
+ break;
- if (tp->flag == NULL)
- {
- as_bad ("unknown architecture: %s", p);
- }
- else
- {
- architecture = tp->arch;
- }
- }
- else
- {
- /* Unknown option */
- (*argP)++;
+ default:
return 0;
}
- **argP = '\0'; /* Done parsing this switch */
+
return 1;
}
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, "\
+I960 options:\n\
+-ACA | -ACA_A | -ACB | -ACC | -AKA | -AKB | -AKC | -AMC\n\
+ specify variant of 960 architecture\n\
+-b add code to collect statistics about branches taken\n\
+-linkrelax make relocatable instructions undefined (?)\n\
+-norelax don't alter compare-and-branch instructions for\n\
+ long displacements\n");
+}
+\f
+
/*****************************************************************************
* md_convert_frag:
* Called by base assembler after address relaxation is finished: modify
| (ri->r_bsr << 4)
| (ri->r_disp << 5)
| (ri->r_callj << 6));
-} /* md_ri_to_chars() */
+}
#ifndef WORKING_DOT_WORD
1,
NO_RELOC);
- fixP->fx_callj = callj;
+ fixP->fx_tcbit = callj;
/* We want to modify a bit field when the address is
* known. But we don't need all the garbage in the
expressionS expr; /* Parsed expression */
fixS *fixP; /*->description of deferred address fixup */
+#ifdef OBJ_COFF
+ /* COFF support isn't in place yet for callx relaxing. */
+ callx = 0;
+#endif
+
memset (&instr, '\0', sizeof (memS));
instr.opcode = oP->opcode;
0,
NO_RELOC);
fixP->fx_im_disp = 2; /* 32-bit displacement fix */
- fixP->fx_bsr = callx; /*SAC LD RELAX HACK *//* Mark reloc as being in i stream */
+ /* Steve's linker relaxing hack. Mark this 32-bit relocation as
+ being in the instruction stream, specifically as part of a callx
+ instruction. */
+ fixP->fx_bsr = callx;
break;
}
} /* memfmt() */
{
char *where; /*->the binary for the instruction being relocated */
- if (!fixP->fx_callj)
+ if (!fixP->fx_tcbit)
{
return;
} /* This wasn't a callj instruction in the first place */
} /* switch on proc type */
/* else Symbol is neither a sysproc nor a leafproc */
-
- return;
-} /* reloc_callj() */
+}
/*****************************************************************************
tc_set_bal_of_call (callP, balP);
} /* if only one arg, or the args are the same */
-
- return;
-} /* s_leafproc() */
+}
/*
TC_S_SET_SYSPROC (symP, offs (exp)); /* encode entry number */
TC_S_FORCE_TO_SYSPROC (symP);
-
- return;
-} /* s_sysproc() */
+}
/*****************************************************************************
* Return TRUE iff the target architecture supports the specified
* special-function register (sfr).
*
- **************************************************************************** */
+ *****************************************************************************/
static
int
targ_has_sfr (n)
* Return TRUE iff the target architecture supports the indicated
* class of instructions.
*
- **************************************************************************** */
+ *****************************************************************************/
static
int
targ_has_iclass (ic)
char *name;
{
return 0;
-} /* md_undefined_symbol() */
+}
/* Exactly what point is a PC-relative offset relative TO?
On the i960, they're relative to the address of the instruction,
char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
if (!fixP->fx_bit_fixP)
- {
-
- switch (fixP->fx_im_disp)
- {
- case 0:
- fixP->fx_addnumber = val;
- md_number_to_imm (place, val, fixP->fx_size, fixP);
- break;
- case 1:
- md_number_to_disp (place,
- (fixP->fx_pcrel
- ? val + fixP->fx_pcrel_adjust
- : val),
- fixP->fx_size);
- break;
- case 2: /* fix requested for .long .word etc */
- md_number_to_chars (place, val, fixP->fx_size);
- break;
- default:
- as_fatal ("Internal error in md_apply_fix() in file \"%s\"",
- __FILE__);
- }
- }
+ switch (fixP->fx_im_disp)
+ {
+ case 0:
+ /* For callx, we always want to write out zero, and emit a
+ symbolic relocation. */
+ if (fixP->fx_bsr)
+ val = 0;
+
+ fixP->fx_addnumber = val;
+ md_number_to_imm (place, val, fixP->fx_size, fixP);
+ break;
+ case 1:
+ md_number_to_disp (place,
+ (fixP->fx_pcrel
+ ? val + fixP->fx_pcrel_adjust
+ : val),
+ fixP->fx_size);
+ break;
+ case 2: /* fix requested for .long .word etc */
+ md_number_to_chars (place, val, fixP->fx_size);
+ break;
+ default:
+ as_fatal ("Internal error in md_apply_fix() in file \"%s\"",
+ __FILE__);
+ }
else
- {
- md_number_to_field (place, val, fixP->fx_bit_fixP);
- }
-
- return;
-} /* md_apply_fix() */
+ md_number_to_field (place, val, fixP->fx_bit_fixP);
+}
#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
void
fixS *fixP;
relax_addressT segment_address_in_file;
{
- static unsigned char nbytes_r_length[] =
- {42, 0, 1, 42, 2};
+ static const unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
struct relocation_info ri;
symbolS *symbolP;
- /* JF this is for paranoia */
memset ((char *) &ri, '\0', sizeof (ri));
symbolP = fixP->fx_addsy;
know (symbolP != 0 || fixP->fx_r_type != NO_RELOC);
ri.r_bsr = fixP->fx_bsr; /*SAC LD RELAX HACK */
/* These two 'cuz of NS32K */
- ri.r_callj = fixP->fx_callj;
+ ri.r_callj = fixP->fx_tcbit;
if (fixP->fx_bit_fixP)
- {
- ri.r_length = 2;
- }
+ ri.r_length = 2;
else
- {
- ri.r_length = nbytes_r_length[fixP->fx_size];
- }
+ ri.r_length = nbytes_r_length[fixP->fx_size];
ri.r_pcrel = fixP->fx_pcrel;
ri.r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file;
}
ri.r_extern = 0;
}
- else if (linkrelax || !S_IS_DEFINED (symbolP))
+ else if (linkrelax || !S_IS_DEFINED (symbolP) || fixP->fx_bsr)
{
ri.r_extern = 1;
ri.r_index = symbolP->sy_number;
/* Output the relocation information in machine-dependent form. */
md_ri_to_chars (where, &ri);
-
- return;
-} /* tc_bout_fix_to_chars() */
+}
#endif /* OBJ_AOUT or OBJ_BOUT */
-/* Align an address by rounding it up to the specified boundary.
- */
+#if defined (OBJ_COFF) && defined (BFD)
+short
+tc_coff_fix2rtype (fixP)
+ fixS *fixP;
+{
+ if (fixP->fx_bsr)
+ abort ();
+
+ if (fixP->fx_pcrel == 0 && fixP->fx_size == 4)
+ return R_RELLONG;
+
+ if (fixP->fx_pcrel != 0 && fixP->fx_size == 4)
+ return R_IPRMED;
+
+ abort ();
+}
+
+int
+tc_coff_sizemachdep (frag)
+ fragS *frag;
+{
+ if (frag->fr_next)
+ return frag->fr_next->fr_address - frag->fr_address;
+ else
+ return 0;
+}
+#endif
+
+/* Align an address by rounding it up to the specified boundary. */
valueT
md_section_align (seg, addr)
segT seg;
tc_headers_hook (headers)
object_headers *headers;
{
- /* FIXME: remove this line *//* unsigned short arch_flag = 0; */
-
if (iclasses_seen == I_BASE)
{
headers->filehdr.f_flags |= F_I960CORE;
headers->filehdr.f_magic = I960ROMAGIC;
headers->aouthdr.magic = NMAGIC;
} /* set magic numbers */
-
- return;
-} /* tc_headers_hook() */
+}
#endif /* OBJ_COFF */
} /* externality mismatch */
} /* if callname */
} /* walk the symbol chain */
-
- return;
-} /* tc_crawl_symbol_chain() */
+}
/*
* For aout or bout, the bal immediately follows the call.
(as yet unwritten.);
#endif /* ! OBJ_ABOUT */
#endif /* ! OBJ_COFF */
-
- return;
-} /* tc_set_bal_of_call() */
+}
char *
_tc_get_bal_of_call (callP)
S_SET_STORAGE_CLASS (balP, C_LABEL);
#endif /* OBJ_COFF */
} /* only on calls */
-
- return;
-} /* tc_coff_symbol_emit_hook() */
+}
void
i960_handle_align (fragp)
if (!linkrelax)
return;
+#ifndef OBJ_BOUT
+
+ as_bad ("option --link-relax is only supported in b.out format");
+ linkrelax = 0;
+ return;
+
+#else
+
/* The text section "ends" with another alignment reloc, to which we
aren't adding padding. */
if (fragp->fr_next == text_last_frag
|| fragp->fr_next == data_last_frag)
- {
- return;
- }
+ return;
/* alignment directive */
fixp = fix_new (fragp, fragp->fr_fix, fragp->fr_offset, 0, 0, 0,
(int) fragp->fr_type);
+#endif /* OBJ_BOUT */
+}
+
+int
+i960_validate_fix (fixP, this_segment_type, add_symbolPP)
+ fixS *fixP;
+ segT this_segment_type;
+ symbolS **add_symbolPP;
+{
+#define add_symbolP (*add_symbolPP)
+ if (fixP->fx_tcbit && TC_S_IS_CALLNAME (add_symbolP))
+ {
+ /* Relocation should be done via the associated 'bal'
+ entry point symbol. */
+
+ if (!TC_S_IS_BALNAME (tc_get_bal_of_call (add_symbolP)))
+ {
+ as_bad ("No 'bal' entry point for leafproc %s",
+ S_GET_NAME (add_symbolP));
+ return 1;
+ }
+ fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
+ }
+#if 0
+ /* Still have to work out other conditions for these tests. */
+ {
+ if (fixP->fx_tcbit)
+ {
+ as_bad ("callj to difference of two symbols");
+ return 1;
+ }
+ reloc_callj (fixP);
+ if ((int) fixP->fx_bit_fixP == 13)
+ {
+ /* This is a COBR instruction. They have only a 13-bit
+ displacement and are only to be used for local branches:
+ flag as error, don't generate relocation. */
+ as_bad ("can't use COBR format with external label");
+ fixP->fx_addsy = NULL; /* No relocations please. */
+ return 1;
+ }
+ }
+#endif
+#undef add_symbolP
+ return 0;
}
/* end of tc-i960.c */
/* s_space is defined in read.c .skip is simply an alias to it. */
+\f
/*
* md_parse_option
* Invocation line includes a switch not recognized by the base assembler.
#define MAYBE_FLOAT_TOO /* m68881 */ 0 /* this is handled later */
#endif
-int
-m68k_parse_long_option (opt)
- char *opt;
-{
- /* Skip over double-dash. */
- opt += 2;
- if (!strcmp (opt, "register-prefix-optional"))
- {
- flag_reg_prefix_optional = 1;
- return 1;
- }
- return 0;
-}
+CONST char *md_shortopts = "lSA:m:k";
+struct option md_longopts[] = {
+#define OPTION_PIC (OPTION_MD_BASE)
+ {"pic", no_argument, NULL, OPTION_PIC},
+#define OPTION_REGISTER_PREFIX_OPTIONAL (OPTION_MD_BASE + 1)
+ {"register-prefix-optional", no_argument, NULL,
+ OPTION_REGISTER_PREFIX_OPTIONAL},
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
int
-md_parse_option (argP, cntP, vecP)
- char **argP;
- int *cntP;
- char ***vecP;
+md_parse_option (c, arg)
+ int c;
+ char *arg;
{
- switch (**argP)
+ switch (c)
{
case 'l': /* -l means keep external to 2 bit offset
rather than 16 bit one */
break;
case 'A':
- (*argP)++;
+ if (*arg == 'm')
+ arg++;
/* intentional fall-through */
case 'm':
- (*argP)++;
-
- if (**argP == 'c')
- {
- (*argP)++;
- } /* allow an optional "c" */
+ if (*arg == 'c')
+ arg++;
- if (!strcmp (*argP, "68000")
- || !strcmp (*argP, "68008")
- || !strcmp (*argP, "68302"))
+ if (!strcmp (arg, "68000")
+ || !strcmp (arg, "68008")
+ || !strcmp (arg, "68302"))
{
current_architecture |= m68000;
}
- else if (!strcmp (*argP, "68010"))
+ else if (!strcmp (arg, "68010"))
{
current_architecture |= m68010;
}
- else if (!strcmp (*argP, "68020"))
+ else if (!strcmp (arg, "68020"))
{
current_architecture |= m68020 | MAYBE_FLOAT_TOO;
}
- else if (!strcmp (*argP, "68030"))
+ else if (!strcmp (arg, "68030"))
{
current_architecture |= m68030 | MAYBE_FLOAT_TOO;
}
- else if (!strcmp (*argP, "68040"))
+ else if (!strcmp (arg, "68040"))
{
current_architecture |= m68040 | MAYBE_FLOAT_TOO;
}
- else if (!strcmp (*argP, "68060"))
+ else if (!strcmp (arg, "68060"))
{
current_architecture |= m68060 | MAYBE_FLOAT_TOO;
}
#ifndef NO_68881
- else if (!strcmp (*argP, "68881"))
+ else if (!strcmp (arg, "68881"))
{
current_architecture |= m68881;
}
- else if (!strcmp (*argP, "68882"))
+ else if (!strcmp (arg, "68882"))
{
current_architecture |= m68882;
}
/* Even if we aren't configured to support the processor,
it should still be possible to assert that the user
doesn't have it... */
- else if (!strcmp (*argP, "no-68881")
- || !strcmp (*argP, "no-68882"))
+ else if (!strcmp (arg, "no-68881")
+ || !strcmp (arg, "no-68882"))
{
no_68881 = 1;
}
#ifndef NO_68851
- else if (!strcmp (*argP, "68851"))
+ else if (!strcmp (arg, "68851"))
{
current_architecture |= m68851;
}
#endif /* NO_68851 */
- else if (!strcmp (*argP, "no-68851"))
+ else if (!strcmp (arg, "no-68851"))
{
no_68851 = 1;
}
- else if (!strcmp (*argP, "pu32") /* "cpu32" minus 'c' */
- || !strcmp (*argP, "68331")
- || !strcmp (*argP, "68332")
- || !strcmp (*argP, "68333")
- || !strcmp (*argP, "68340"))
+ else if (!strcmp (arg, "pu32") /* "cpu32" minus 'c' */
+ || !strcmp (arg, "68331")
+ || !strcmp (arg, "68332")
+ || !strcmp (arg, "68333")
+ || !strcmp (arg, "68340"))
{
current_architecture |= cpu32;
}
else
{
- as_warn ("Unknown architecture, \"%s\". option ignored", *argP);
- } /* switch on architecture */
-
- while (**argP)
- (*argP)++;
-
- break;
-
- case 'p':
- if (!strcmp (*argP, "pic"))
- {
- *argP += 3;
- flag_want_pic = 1;
- break; /* -pic, Position Independent Code */
+ as_bad ("invalid architecture %s", arg);
+ return 0;
}
- else
- goto bad_arg;
+ break;
-#ifdef TE_SUN3
+ case OPTION_PIC:
case 'k':
flag_want_pic = 1;
+ break; /* -pic, Position Independent Code */
+
+ case OPTION_REGISTER_PREFIX_OPTIONAL:
+ flag_reg_prefix_optional = 1;
break;
-#endif
default:
- bad_arg:
return 0;
}
+
return 1;
}
-
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, "\
+680X0 options:\n\
+-l use 1 word for refs to undefined symbols [default 2]\n\
+-m68000 | -m68008 | -m68010 | -m68020 | -m68030 | -m68040\n\
+ | -m68302 | -m68331 | -m68332 | -m68333 | -m68340 | -mcpu32\n\
+ specify variant of 680X0 architecture [default 68020]\n\
+-m68881 | -m68882 | -mno-68881 | -mno-68882\n\
+ target has/lacks floating-point coprocessor\n\
+ [default yes for 68020, 68030, and cpu32]\n\
+-m68851 | -mno-68851\n\
+ target has/lacks memory-management unit coprocessor\n\
+ [default yes for 68020 and up]\n\
+-pic, -k generate position independent code\n\
+-S turn jbsr into jsr\n\
+--register-prefix-optional\n\
+ recognize register names without prefix character\n");
+}
+\f
#ifdef TEST2
/* TEST2: Test md_assemble() */
;
}
}
+\f
+CONST char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
int
-md_parse_option (argP, cntP, vecP)
- char **argP;
- int *cntP;
- char ***vecP;
+md_parse_option (c, arg)
+ int c;
+ char *arg;
{
return 0;
}
void
+md_show_usage (stream)
+ FILE *stream;
+{
+}
+\f
+void
md_assemble (op)
char *op;
{
internalError ();
}
}
+\f
+#ifdef GPOPT
+CONST char *md_shortopts = "E:O::g::G:";
+#else
+CONST char *md_shortopts = "E:O::g::";
+#endif
+struct option md_longopts[] = {
+#define OPTION_MIPS1 (OPTION_MD_BASE + 1)
+ {"mips0", no_argument, NULL, OPTION_MIPS1},
+ {"mips1", no_argument, NULL, OPTION_MIPS1},
+#define OPTION_MIPS2 (OPTION_MD_BASE + 2)
+ {"mips2", no_argument, NULL, OPTION_MIPS2},
+#define OPTION_MIPS3 (OPTION_MD_BASE + 3)
+ {"mips3", no_argument, NULL, OPTION_MIPS3},
+#define OPTION_MCPU (OPTION_MD_BASE + 4)
+ {"mcpu", required_argument, NULL, OPTION_MCPU},
+#define OPTION_MEMBEDDED_PIC (OPTION_MD_BASE + 5)
+ {"membedded-pic", no_argument, NULL, OPTION_MEMBEDDED_PIC},
+#define OPTION_TRAP (OPTION_MD_BASE + 8)
+ {"trap", no_argument, NULL, OPTION_TRAP},
+ {"no-break", no_argument, NULL, OPTION_TRAP},
+#define OPTION_BREAK (OPTION_MD_BASE + 9)
+ {"break", no_argument, NULL, OPTION_BREAK},
+ {"no-trap", no_argument, NULL, OPTION_BREAK},
+
+#ifdef OBJ_ELF
+#define OPTION_CALL_SHARED (OPTION_MD_BASE + 6)
+ {"KPIC", no_argument, NULL, OPTION_CALL_SHARED},
+ {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
+#define OPTION_NON_SHARED (OPTION_MD_BASE + 7)
+ {"non_shared", no_argument, NULL, OPTION_NON_SHARED},
+#endif
+
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
int
-md_parse_option (argP, cntP, vecP)
- char **argP;
- int *cntP;
- char ***vecP;
+md_parse_option (c, arg)
+ int c;
+ char *arg;
{
- /* Accept -nocpp but ignore it. */
- if (strcmp (*argP, "nocpp") == 0)
+ switch (c)
{
- *argP += 5;
- return 1;
- }
+ case OPTION_TRAP:
+ mips_trap = 1;
+ break;
- if (strcmp (*argP, "EL") == 0
- || strcmp (*argP, "EB") == 0)
- {
- if ((*argP)[1] == 'B')
+ case OPTION_BREAK:
+ mips_trap = 0;
+ break;
+
+ case 'E':
+ if (arg[1] == 'B')
byte_order = BIG_ENDIAN;
- else
+ else if (arg[1] == 'L')
byte_order = LITTLE_ENDIAN;
+ else
+ {
+ as_bad("invalid endianness -E%c", arg[1]);
+ return 0;
+ }
#ifdef OBJ_AOUT
- if ((*argP)[1] == 'B')
+ if (arg[1] == 'B')
mips_target_format = "a.out-mips-big";
else
mips_target_format = "a.out-mips-little";
#endif
#ifdef OBJ_ECOFF
- if ((*argP)[1] == 'B')
+ if (arg[1] == 'B')
mips_target_format = "ecoff-bigmips";
else
mips_target_format = "ecoff-littlemips";
#endif
#ifdef OBJ_ELF
- if ((*argP)[1] == 'B')
+ if (arg[1] == 'B')
mips_target_format = "elf32-bigmips";
else
mips_target_format = "elf32-littlemips";
/* FIXME: This breaks -L -EL. */
flagseen['L'] = 0;
- *argP = "";
- return 1;
- }
+ break;
- if (**argP == 'O')
- {
- if ((*argP)[1] == '0')
+ case 'O':
+ if (arg && arg[1] == '0')
mips_optimize = 1;
else
mips_optimize = 2;
- return 1;
- }
+ break;
- if (**argP == 'g')
- {
- if ((*argP)[1] == '\0' || (*argP)[1] == '2')
+ case 'g':
+ if (arg == NULL || arg[1] == '2')
mips_optimize = 0;
- return 1;
- }
+ break;
- if (strncmp (*argP, "mips", 4) == 0)
- {
- mips_isa = atol (*argP + 4);
- if (mips_isa == 0)
- mips_isa = 1;
- else if (mips_isa < 1 || mips_isa > 3)
- {
- as_bad ("-mips%d not supported", mips_isa);
- mips_isa = 1;
- }
- *argP = "";
- return 1;
- }
+ case OPTION_MIPS1:
+ mips_isa = 1;
+ break;
- if (strncmp (*argP, "mcpu=", 5) == 0)
- {
- char *p;
+ case OPTION_MIPS2:
+ mips_isa = 2;
+ break;
- /* Identify the processor type */
- p = *argP + 5;
- if (strcmp (p, "default") == 0
- || strcmp (p, "DEFAULT") == 0)
- mips_isa = -1;
- else
- {
- if (*p == 'r' || *p == 'R')
- p++;
+ case OPTION_MIPS3:
+ mips_isa = 3;
+ break;
+
+ case OPTION_MCPU:
+ {
+ char *p;
+ /* Identify the processor type */
+ p = arg;
+ if (strcmp (p, "default") == 0
+ || strcmp (p, "DEFAULT") == 0)
mips_isa = -1;
- switch (*p)
- {
- case '2':
- if (strcmp (p, "2000") == 0
- || strcmp (p, "2k") == 0
- || strcmp (p, "2K") == 0)
- mips_isa = 1;
- break;
+ else
+ {
+ if (*p == 'r' || *p == 'R')
+ p++;
- case '3':
- if (strcmp (p, "3000") == 0
- || strcmp (p, "3k") == 0
- || strcmp (p, "3K") == 0)
- mips_isa = 1;
- break;
+ mips_isa = -1;
+ switch (*p)
+ {
+ case '2':
+ if (strcmp (p, "2000") == 0
+ || strcmp (p, "2k") == 0
+ || strcmp (p, "2K") == 0)
+ mips_isa = 1;
+ break;
- case '4':
- if (strcmp (p, "4000") == 0
- || strcmp (p, "4k") == 0
- || strcmp (p, "4K") == 0)
- mips_isa = 3;
- break;
+ case '3':
+ if (strcmp (p, "3000") == 0
+ || strcmp (p, "3k") == 0
+ || strcmp (p, "3K") == 0)
+ mips_isa = 1;
+ break;
- case '6':
- if (strcmp (p, "6000") == 0
- || strcmp (p, "6k") == 0
- || strcmp (p, "6K") == 0)
- mips_isa = 2;
- break;
- }
+ case '4':
+ if (strcmp (p, "4000") == 0
+ || strcmp (p, "4k") == 0
+ || strcmp (p, "4K") == 0)
+ mips_isa = 3;
+ break;
- if (mips_isa == -1)
- {
- as_bad ("bad value (%s) for -mcpu= switch", *argP + 5);
- mips_isa = 1;
- }
- }
+ case '6':
+ if (strcmp (p, "6000") == 0
+ || strcmp (p, "6k") == 0
+ || strcmp (p, "6K") == 0)
+ mips_isa = 2;
+ break;
+ }
- *argP = "";
- return 1;
- }
+ if (mips_isa == -1)
+ {
+ as_bad ("invalid architecture -mcpu=%s", arg);
+ return 0;
+ }
+ }
+ }
+ break;
- /* Argument -membedded-pic means to use EMBEDDED_PIC. */
- if (strcmp (*argP, "membedded-pic") == 0)
- {
+ case OPTION_MEMBEDDED_PIC:
mips_pic = EMBEDDED_PIC;
#ifdef GPOPT
if (g_switch_seen)
- as_warn ("-G may not be used with embedded PIC code");
+ {
+ as_bad ("-G may not be used with embedded PIC code");
+ return 0;
+ }
g_switch_value = 0x7fffffff;
#endif
- *argP = "";
- return 1;
- }
+ break;
#ifdef OBJ_ELF
/* When generating ELF code, we permit -KPIC and -call_shared to
select SVR4_PIC, and -non_shared to select no PIC. This is
intended to be compatible with Irix 5. */
- if (strcmp (*argP, "KPIC") == 0
- || strcmp (*argP, "call_shared") == 0)
- {
+ case OPTION_CALL_SHARED:
mips_pic = SVR4_PIC;
if (g_switch_seen && g_switch_value != 0)
- as_warn ("-G may not be used with SVR4 PIC code");
+ {
+ as_bad ("-G may not be used with SVR4 PIC code");
+ return 0;
+ }
g_switch_value = 0;
- *argP = "";
- return 1;
- }
- else if (strcmp (*argP, "non_shared") == 0)
- {
+ break;
+
+ case OPTION_NON_SHARED:
mips_pic = NO_PIC;
- *argP = "";
- return 1;
- }
+ break;
#endif /* OBJ_ELF */
#ifdef GPOPT
- if (**argP == 'G')
- {
+ case 'G':
if (mips_pic == SVR4_PIC || mips_pic == EMBEDDED_PIC)
- as_warn ("-G may not be used with SVR4 or embedded PIC code");
- else if ((*argP)[1] != '\0')
- g_switch_value = atoi (*argP + 1);
- else if (*cntP)
{
- **vecP = (char *) NULL;
- (*cntP)--;
- (*vecP)++;
- g_switch_value = atoi (**vecP);
+ as_bad ("-G may not be used with SVR4 or embedded PIC code");
+ return 0;
}
else
- as_warn ("Number expected after -G");
+ g_switch_value = atoi (arg);
g_switch_seen = 1;
- *argP = "";
- return 1;
- }
+ break;
#endif
- return 1; /* pretend you parsed the character */
-}
-
-/* Handle a long option name. */
-
-int
-mips_parse_long_option (arg)
- const char *arg;
-{
- if (strcmp (arg, "--trap") == 0
- || strcmp (arg, "--no-break") == 0)
- {
- mips_trap = 1;
- return 1;
- }
- else if (strcmp (arg, "--no-trap") == 0
- || strcmp (arg, "--break") == 0)
- {
- mips_trap = 0;
- return 1;
+ default:
+ return 0;
}
- return 0;
+ return 1;
}
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, "\
+MIPS options:\n\
+-membedded-pic generate embedded position independent code\n\
+-nocpp ignored\n\
+-EB generate big endian output\n\
+-EL generate little endian output\n\
+-g, -g2 do not remove uneeded NOPs or swap branches\n\
+-G NUM allow referencing objects up to NUM bytes\n\
+ implicitly with the gp register [default 8]\n\
+-mips1, -mcpu=r{2,3}000 generate code for r2000 and r3000\n\
+-mips2, -mcpu=r6000 generate code for r6000\n\
+-mips3, -mcpu=r4000 generate code for r4000\n\
+-O0 remove unneeded NOPs, do not swap branches\n\
+-O remove unneeded NOPs and swap branches\n\
+--trap, --no-break trap exception on div by 0 and mult overflow\n\
+--break, --no-trap break exception on div by 0 and mult overflow\n");
+#ifdef OBJ_ELF
+ fprintf(stream, "\
+-KPIC, -call_shared generate SVR4 position independent code\n\
+-non_shared do not generate position independent code\n");
+#endif
+}
+\f
long
md_pcrel_from (fixP)
fixS *fixP;
fprintf (stderr, "}\n");
}
#endif
-
+\f
/*
* md_parse_option
* Invocation line includes a switch not recognized by the base assembler.
* end-sanitize-v9
*/
-int
-md_parse_option (argP, cntP, vecP)
- char **argP;
- int *cntP;
- char ***vecP;
-{
- char *p;
- const char **arch;
+#ifdef OBJ_ELF
+CONST char *md_shortopts = "A:VQ:sq";
+#else
+CONST char *md_shortopts = "A:";
+#endif
+struct option md_longopts[] = {
+#define OPTION_BUMP (OPTION_MD_BASE)
+ {"bump", no_argument, NULL, OPTION_BUMP},
+#define OPTION_SPARC (OPTION_MD_BASE + 1)
+ {"sparc", no_argument, NULL, OPTION_SPARC},
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
- if (!strcmp (*argP, "bump"))
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
{
+ case OPTION_BUMP:
warn_on_bump = 1;
- }
- else if (**argP == 'A')
- {
- p = (*argP) + 1;
+ break;
- for (arch = architecture_pname; *arch != NULL; ++arch)
- {
- if (strcmp (p, *arch) == 0)
- {
+ case 'A':
+ {
+ char *p = arg;
+ const char **arch;
+
+ for (arch = architecture_pname; *arch != NULL; ++arch)
+ {
+ if (strcmp (p, *arch) == 0)
break;
- } /* found a match */
- } /* walk the pname table */
+ }
+
+ if (*arch == NULL)
+ {
+ as_bad ("invalid architecture -A%s", p);
+ return 0;
+ }
+ else
+ {
+ current_architecture = (enum sparc_architecture)
+ (arch - architecture_pname);
+ architecture_requested = 1;
+ }
+ }
+ break;
+
+ case OPTION_SPARC:
+ /* Ignore -sparc, used by SunOS make default .s.o rule. */
+ break;
- if (*arch == NULL)
- {
- as_bad ("unknown architecture: %s", p);
- }
- else
- {
- current_architecture = (enum sparc_architecture) (arch - architecture_pname);
- architecture_requested = 1;
- }
- }
#ifdef OBJ_ELF
- else if (**argP == 'V')
- {
+ case 'V':
print_version_id ();
- }
- else if (**argP == 'Q')
- {
+ break;
+
+ case 'Q':
/* Qy - do emit .comment
Qn - do not emit .comment */
- }
- else if (**argP == 's')
- {
+ break;
+
+ case 's':
/* use .stab instead of .stab.excl */
- }
- else if (**argP == 'q')
- {
+ break;
+
+ case 'q':
/* quick -- native assembler does fewer checks */
- }
+ break;
#endif
- else if (strcmp (*argP, "sparc") == 0)
- {
- /* Ignore -sparc, used by SunOS make default .s.o rule. */
- }
- else
- {
- /* Unknown option */
- (*argP)++;
+
+ default:
return 0;
}
- **argP = '\0'; /* Done parsing this switch */
- return 1;
-} /* md_parse_option() */
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, "\
+SPARC options:\n\
+-Av6 | -Av7 | -Av8 | -Asparclite\n\
+ specify variant of SPARC architecture\n\
+-bump warn when assembler switches architectures\n\
+-sparc ignored\n");
+#ifdef OBJ_ELF
+ fprintf(stream, "\
+-V print assembler version number\n\
+-q ignored\n\
+-Qy, -Qn ignored\n\
+-s ignored\n");
+#endif
+}
+\f
/* We have no need to default values of symbols. */
/* ARGSUSED */
as_fatal (errorval);
}
\f
+CONST char *md_shortopts = "ad:STt:V";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
int
-md_parse_option (argP, cntP, vecP)
- char **argP;
- int *cntP;
- char ***vecP;
+md_parse_option (c, arg)
+ int c;
+ char *arg;
{
- char *temp_name; /* name for -t or -d options */
- char opt;
-
- switch (**argP)
+ switch (c)
{
case 'a':
- as_warn ("The -a option doesn't exits. (Dispite what the man page says!");
+ as_warn ("The -a option doesn't exist. (Despite what the man page says!");
+ break;
- case 'J':
- as_warn ("JUMPIFY (-J) not implemented, use psuedo ops instead.");
+ case 'd':
+ as_warn ("Displacement length %s ignored!", arg);
break;
case 'S':
as_warn ("SYMBOL TABLE not implemented");
- break; /* SYMBOL TABLE not implemented */
+ break;
case 'T':
as_warn ("TOKEN TRACE not implemented");
- break; /* TOKEN TRACE not implemented */
+ break;
- case 'd':
case 't':
- opt = **argP;
- if (**argP)
- { /* Rest of argument is filename. */
- temp_name = *argP;
- while (**argP)
- (*argP)++;
- }
- else if (*cntP)
- {
- while (**argP)
- (*argP)++;
- --(*cntP);
- temp_name = *++(*vecP);
- **vecP = NULL; /* Remember this is not a file-name. */
- }
- else
- {
- as_warn ("I expected a filename after -%c.", opt);
- temp_name = "{absent}";
- }
-
- if (opt == 'd')
- as_warn ("Displacement length %s ignored!", temp_name);
- else
- as_warn ("I don't need or use temp. file \"%s\".", temp_name);
+ as_warn ("I don't need or use temp. file \"%s\".", arg);
break;
case 'V':
default:
return 0;
-
}
+
return 1;
}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, "\
+Tahoe options:\n\
+-a ignored\n\
+-d LENGTH ignored\n\
+-J ignored\n\
+-S ignored\n\
+-t FILE ignored\n\
+-T ignored\n\
+-V ignored\n");
+}
\f
/* The functions in this section take numbers in the machine format, and
munges them into Tahoe byte order.
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-/* JF I moved almost all the vax specific stuff into this one file 'cuz RMS
- seems to think its a good idea. I hope I managed to get all the VAX-isms */
-
-
#include "as.h"
#include "vax-inst.h"
/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
changed in read.c . Ideally it shouldn't have to know about it at all,
- but nothing is ideal around here.
- */
+ but nothing is ideal around here. */
-static expressionS /* Hold details of an operand expression */
- exp_of_operand[VIT_MAX_OPERANDS];
+/* Hold details of an operand expression */
+static expressionS exp_of_operand[VIT_MAX_OPERANDS];
+static segT seg_of_operand[VIT_MAX_OPERANDS];
-static struct vit
- v; /* A vax instruction after decoding. */
+/* A vax instruction after decoding. */
+static struct vit v;
-LITTLENUM_TYPE big_operand_bits[VIT_MAX_OPERANDS][SIZE_OF_LARGE_NUMBER];
/* Hold details of big operands. */
+LITTLENUM_TYPE big_operand_bits[VIT_MAX_OPERANDS][SIZE_OF_LARGE_NUMBER];
FLONUM_TYPE float_operand[VIT_MAX_OPERANDS];
-/* Above is made to point into */
-/* big_operand_bits by md_begin(). */
+/* Above is made to point into big_operand_bits by md_begin(). */
\f
/*
* For VAX, relative addresses of "just the right length" are easy.
after relax() what the original addressing mode was.
*/
\f
-/* These displacements are relative to */
-/* the start address of the displacement. */
-/* The first letter is Byte, Word. */
-/* 2nd letter is Forward, Backward. */
+/* These displacements are relative to the start address of the
+ displacement. The first letter is Byte, Word. 2nd letter is
+ Forward, Backward. */
#define BF (1+ 127)
#define BB (1+-128)
#define WF (2+ 32767)
#define WB (2+-32768)
-/* Dont need LF, LB because they always */
-/* reach. [They are coded as 0.] */
+/* Dont need LF, LB because they always reach. [They are coded as 0.] */
#define C(a,b) ENCODE_RELAX(a,b)
#define min(a, b) ((a) < (b) ? (a) : (b))
-#if __STDC__ == 1
-
-int flonum_gen2vax (char format_letter, FLONUM_TYPE * f, LITTLENUM_TYPE * words);
-static void vip_end (void);
-static void vip_op_defaults (char *immediate, char *indirect, char *displen);
-
-#else /* not __STDC__ */
-
-int flonum_gen2vax ();
-static void vip_end ();
-static void vip_op_defaults ();
-
-#endif /* not __STDC__ */
+int flonum_gen2vax PARAMS ((char format_letter, FLONUM_TYPE * f,
+ LITTLENUM_TYPE * words));
+static const char *vip_begin PARAMS ((int, char *, char *, char *));
+static void vip_op_defaults PARAMS ((char *immediate, char *indirect,
+ char *displen));
+static void vip_op PARAMS ((char *, struct vop *));
+static void vip PARAMS ((struct vit *, char *));
void
md_begin ()
{
- char *vip_begin ();
- char *errtxt;
+ const char *errtxt;
FLONUM_TYPE *fP;
int i;
- if (*(errtxt = vip_begin (1, "$", "*", "`")))
+ if (errtxt = vip_begin (1, "$", "*", "`"))
{
as_fatal ("VIP_BEGIN error:%s", errtxt);
}
fP->high = &big_operand_bits[i][SIZE_OF_LARGE_NUMBER - 1];
}
}
-
-void
-md_end ()
-{
- vip_end ();
-}
\f
-void /* Knows about order of bytes in address. */
+void
md_number_to_chars (con, value, nbytes)
- char con[]; /* Return 'nbytes' of chars here. */
- valueT value; /* The value of the bits. */
- int nbytes; /* Number of bytes in the output. */
+ char con[];
+ valueT value;
+ int nbytes;
{
- int n;
- valueT v;
-
- n = nbytes;
- v = value;
- while (nbytes--)
- {
- *con++ = value; /* Lint wants & MASK_CHAR. */
- value >>= BITS_PER_CHAR;
- }
- /* XXX line number probably botched for this warning message. */
- if (value != 0 && value != -1)
- as_bad ("Displacement (%ld) long for instruction field length (%d).", v, n);
+ number_to_chars_littleendian (con, value, nbytes);
}
/* Fix up some data or instructions after we find out the value of a symbol
void /* Knows about order of bytes in address. */
md_apply_fix (fixP, value)
- fixS *fixP; /* Fixup struct pointer */
- long value; /* The value of the bits. */
+ fixS *fixP;
+ long value;
{
- char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
- int nbytes; /* Number of bytes in the output. */
-
- nbytes = fixP->fx_size;
- while (nbytes--)
- {
- *buf++ = value; /* Lint wants & MASK_CHAR. */
- value >>= BITS_PER_CHAR;
- }
+ number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal,
+ (valueT) value, fixP->fx_size);
}
-long /* Knows about the byte order in a word. */
+long
md_chars_to_number (con, nbytes)
unsigned char con[]; /* Low order byte 1st. */
int nbytes; /* Number of bytes in the input. */
md_assemble (instruction_string)
char *instruction_string; /* A string: assemble 1 instruction. */
{
- /* We saw no errors in any operands - try to make frag(s) */
- int is_undefined; /* 1 if operand expression's */
- /* segment not known yet. */
- int length_code;
+ /* Non-zero if operand expression's segment is not known yet. */
+ int is_undefined;
+ int length_code;
char *p;
- register struct vop *operandP;/* An operand. Scans all operands. */
+ /* An operand. Scans all operands. */
+ struct vop *operandP;
char *save_input_line_pointer;
- char c_save; /* What used to live after an expression. */
- /* fixme: unused? */
- /* struct frag *fragP; *//* Fragment of code we just made. */
- register int goofed; /* 1: instruction_string bad for all passes. */
- register struct vop *end_operandP; /* -> slot just after last operand */
- /* Limit of the for (each operand). */
- register expressionS *expP; /* -> expression values for this operand */
+ /* What used to live after an expression. */
+ char c_save;
+ /* 1: instruction_string bad for all passes. */
+ int goofed;
+ /* Points to slot just after last operand. */
+ struct vop *end_operandP;
+ /* Points to expression values for this operand. */
+ expressionS *expP;
+ segT *segP;
/* These refer to an instruction operand expression. */
- segT to_seg; /* Target segment of the address. */
- register valueT this_add_number;
- register struct symbol *this_add_symbol; /* +ve (minuend) symbol. */
- register struct symbol *this_subtract_symbol; /* -ve(subtrahend) symbol. */
-
- long opcode_as_number; /* As a number. */
- char *opcode_as_chars; /* Least significant byte 1st. */
+ /* Target segment of the address. */
+ segT to_seg;
+ valueT this_add_number;
+ /* Positive (minuend) symbol. */
+ struct symbol *this_add_symbol;
+ /* As a number. */
+ long opcode_as_number;
+ /* Least significant byte 1st. */
+ char *opcode_as_chars;
/* As an array of characters. */
- char *opcode_low_byteP; /* Least significant byte 1st */
- /* richfix: unused? */
- /* struct details *detP; *//* The details of an ADxxx frag. */
- int length; /* length (bytes) meant by vop_short. */
- int at; /* 0, or 1 if '@' is in addressing mode. */
- int nbytes; /* From vop_nbytes: vax_operand_width (in bytes) */
+ /* Least significant byte 1st */
+ char *opcode_low_byteP;
+ /* length (bytes) meant by vop_short. */
+ int length;
+ /* 0, or 1 if '@' is in addressing mode. */
+ int at;
+ /* From vop_nbytes: vax_operand_width (in bytes) */
+ int nbytes;
FLONUM_TYPE *floatP;
- char *vip ();
LITTLENUM_TYPE literal_float[8];
/* Big enough for any floating point literal. */
- if (*(p = vip (&v, instruction_string)))
- {
- as_fatal ("vax_assemble\"%s\" in=\"%s\"", p, instruction_string);
- }
+ vip (&v, instruction_string);
+
/*
* Now we try to find as many as_warn()s as we can. If we do any as_warn()s
* then goofed=1. Notice that we don't make any frags yet.
save_input_line_pointer = input_line_pointer;
for (operandP = v.vit_operand,
expP = exp_of_operand,
+ segP = seg_of_operand,
floatP = float_operand,
end_operandP = v.vit_operand + v.vit_operands;
operandP < end_operandP;
- operandP++, expP++, floatP++)
+ operandP++, expP++, segP++, floatP++)
{ /* for each operand */
- if (*(operandP->vop_error))
+ if (operandP->vop_error)
{
- as_warn ("Ignoring statement because \"%s\"", (operandP->vop_error));
+ as_warn ("Ignoring statement because \"%s\"", operandP->vop_error);
goofed = 1;
}
else
c_save = operandP->vop_expr_end[1];
operandP->vop_expr_end[1] = '\0';
/* If to_seg == SEG_PASS1, expression() will have set need_pass_2 = 1. */
- switch (to_seg = expression (expP))
+ *segP = expression (expP);
+ switch (expP->X_op)
{
- case SEG_ABSENT:
+ case O_absent:
/* for BSD4.2 compatibility, missing expression is absolute 0 */
- to_seg = expP->X_seg = SEG_ABSOLUTE;
+ expP->X_op = O_constant;
expP->X_add_number = 0;
- /* For SEG_ABSOLUTE, we shouldn't need to set X_subtract_symbol,
+ /* For SEG_ABSOLUTE, we shouldn't need to set X_op_symbol,
X_add_symbol to any particular value. But, we will program
defensively. Since this situation occurs rarely so it costs
us little to do, and stops Dean worrying about the origin of
random bits in expressionS's. */
expP->X_add_symbol = NULL;
- expP->X_subtract_symbol = NULL;
- case SEG_TEXT:
- case SEG_DATA:
- case SEG_BSS:
- case SEG_ABSOLUTE:
- case SEG_UNKNOWN:
+ expP->X_op_symbol = NULL;
break;
- case SEG_DIFFERENCE:
- case SEG_PASS1:
+ case O_symbol:
+ case O_constant:
+ break;
+
+ default:
/*
* Major bug. We can't handle the case of a
- * SEG_DIFFERENCE expression in a VIT_OPCODE_SYNTHETIC
+ * SEG_OP expression in a VIT_OPCODE_SYNTHETIC
* variable-length instruction.
* We don't have a frag type that is smart enough to
- * relax a SEG_DIFFERENCE, and so we just force all
- * SEG_DIFFERENCEs to behave like SEG_PASS1s.
+ * relax a SEG_OP, and so we just force all
+ * SEG_OPs to behave like SEG_PASS1s.
* Clearly, if there is a demand we can invent a new or
* modified frag type and then coding up a frag for this
- * case will be easy. SEG_DIFFERENCE was invented for the
+ * case will be easy. SEG_OP was invented for the
* .words after a CASE opcode, and was never intended for
* instruction operands.
*/
as_warn ("Can't relocate expression");
break;
- case SEG_BIG:
+ case O_big:
/* Preserve the bits. */
if (expP->X_add_number > 0)
{
flonum_copy (&generic_floating_point_number,
floatP);
if (strchr ("s i", operandP->vop_short))
- { /* Could possibly become S^# */
+ {
+ /* Could possibly become S^# */
flonum_gen2vax (-expP->X_add_number, floatP, literal_float);
switch (-expP->X_add_number)
{
{
/* Saw a '#'. */
if (operandP->vop_short == ' ')
- { /* We must chose S^ or I^. */
+ {
+ /* We must chose S^ or I^. */
if (expP->X_add_number > 0)
- { /* Bignum: Short literal impossible. */
+ {
+ /* Bignum: Short literal impossible. */
operandP->vop_short = 'i';
operandP->vop_mode = 8;
operandP->vop_reg = 0xF; /* VAX PC. */
}
else
- { /* Flonum: Try to do it. */
+ {
+ /* Flonum: Try to do it. */
if (can_be_short)
{
operandP->vop_short = 's';
operandP->vop_mode = 0;
operandP->vop_ndx = -1;
operandP->vop_reg = -1;
- /* JF hope this is the right thing */
- expP->X_seg = SEG_ABSOLUTE;
+ expP->X_op = O_constant;
}
else
{
expP->X_add_number = floatP->low[0]
| ((LITTLENUM_MASK & (floatP->low[1])) << LITTLENUM_NUMBER_OF_BITS);
/*
- * For the SEG_BIG case we have:
- * If vop_short == 's' then a short floating literal is in the
- * lowest 6 bits of floatP -> low [0], which is
- * big_operand_bits [---] [0].
- * If vop_short == 'i' then the appropriate number of elements
- * of big_operand_bits [---] [...] are set up with the correct
- * bits.
- * Also, just in case width is byte word or long, we copy the lowest
- * 32 bits of the number to X_add_number.
- */
- break;
-
- default:
- BAD_CASE (to_seg);
+ * For the SEG_BIG case we have:
+ * If vop_short == 's' then a short floating literal is in the
+ * lowest 6 bits of floatP -> low [0], which is
+ * big_operand_bits [---] [0].
+ * If vop_short == 'i' then the appropriate number of elements
+ * of big_operand_bits [---] [...] are set up with the correct
+ * bits.
+ * Also, just in case width is byte word or long, we copy the lowest
+ * 32 bits of the number to X_add_number.
+ */
break;
}
if (input_line_pointer != operandP->vop_expr_end + 1)
opcode_as_number = md_chars_to_number (opcode_as_chars = v.vit_opcode, 4);
for (operandP = v.vit_operand,
expP = exp_of_operand,
+ segP = seg_of_operand,
floatP = float_operand,
end_operandP = v.vit_operand + v.vit_operands;
operandP++,
floatP++,
+ segP++,
expP++)
- { /* for each operand */
+ {
if (operandP->vop_ndx >= 0)
{
/* indexed addressing byte */
/* Here to make main operand frag(s). */
this_add_number = expP->X_add_number;
this_add_symbol = expP->X_add_symbol;
- this_subtract_symbol = expP->X_subtract_symbol;
- to_seg = expP->X_seg;
+ to_seg = *segP;
is_undefined = (to_seg == SEG_UNKNOWN);
know (to_seg == SEG_UNKNOWN
|| to_seg == SEG_ABSOLUTE
{
p = frag_more (nbytes);
fix_new (frag_now, p - frag_now->fr_literal, nbytes,
- this_add_symbol, 0, this_add_number, 1, NO_RELOC);
+ this_add_symbol, this_add_number, 1, NO_RELOC);
}
else
{ /* to_seg==now_seg || to_seg == SEG_UNKNOWN */
}
}
else
- { /* to_seg != now_seg && to_seg != SEG_UNKNOWN */
+ {
+ /* to_seg != now_seg && to_seg != SEG_UNKNOWN */
/*
- * --- SEG FLOAT MAY APPEAR HERE ----
- */
+ * --- SEG FLOAT MAY APPEAR HERE ----
+ */
if (to_seg == SEG_ABSOLUTE)
{
if (nbytes)
p = frag_more (nbytes);
/* Conventional relocation. */
fix_new (frag_now, p - frag_now->fr_literal,
- nbytes, &abs_symbol, 0, this_add_number, 1, NO_RELOC);
+ nbytes, &abs_symbol, this_add_number,
+ 1, NO_RELOC);
}
else
{
p[5] = VAX_ABSOLUTE_MODE; /* @#... */
md_number_to_chars (p + 6, this_add_number, 4);
/*
- * Now (eg) ACBx 1f
- * BRB 2f
- * 1: JMP @#foo
- * 2:
- */
+ * Now (eg) ACBx 1f
+ * BRB 2f
+ * 1: JMP @#foo
+ * 2:
+ */
}
else
{
p[4] = VAX_PC_RELATIVE_MODE + 1; /* @#... */
md_number_to_chars (p + 5, this_add_number, 4);
/*
- * Now (eg) xOBxxx 1f
- * BRB 2f
- * 1: JMP @#foo
- * 2:
- */
+ * Now (eg) xOBxxx 1f
+ * BRB 2f
+ * 1: JMP @#foo
+ * 2:
+ */
}
}
}
{
/* b<cond> */
*opcode_low_byteP ^= 1;
- /* To reverse the condition in a VAX branch, complement the lowest order
- bit. */
+ /* To reverse the condition in a VAX branch,
+ complement the lowest order bit. */
p = frag_more (7);
p[0] = 6;
p[1] = VAX_JMP;
p[2] = VAX_ABSOLUTE_MODE; /* @#... */
md_number_to_chars (p + 3, this_add_number, 4);
/*
- * Now (eg) BLEQ 1f
- * JMP @#foo
- * 1:
- */
+ * Now (eg) BLEQ 1f
+ * JMP @#foo
+ * 1:
+ */
}
}
}
else
- { /* to_seg != now_seg && to_seg != SEG_UNKNOWN && to_Seg != SEG_ABSOLUTE */
+ {
+ /* to_seg != now_seg && to_seg != SEG_UNKNOWN && to_Seg != SEG_ABSOLUTE */
if (nbytes > 0)
{
/* Pc-relative. Conventional relocation. */
know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC));
p = frag_more (nbytes);
fix_new (frag_now, p - frag_now->fr_literal,
- nbytes, &abs_symbol, 0, this_add_number, 1, NO_RELOC);
+ nbytes, &abs_symbol, this_add_number,
+ 1, NO_RELOC);
}
else
{
p[0] = VAX_PC_RELATIVE_MODE;
fix_new (frag_now,
p + 1 - frag_now->fr_literal, 4,
- this_add_symbol, 0,
+ this_add_symbol,
this_add_number, 1, NO_RELOC);
/* Now eg JMP foo or JSB foo. */
}
p[5] = VAX_PC_RELATIVE_MODE;
fix_new (frag_now,
p + 6 - frag_now->fr_literal, 4,
- this_add_symbol, 0,
+ this_add_symbol,
this_add_number, 1, NO_RELOC);
/*
- * Now (eg) ACBx 1f
- * BRB 2f
- * 1: JMP foo
- * 2:
- */
+ * Now (eg) ACBx 1f
+ * BRB 2f
+ * 1: JMP foo
+ * 2:
+ */
}
else
{
p[4] = VAX_PC_RELATIVE_MODE;
fix_new (frag_now,
p + 5 - frag_now->fr_literal,
- 4, this_add_symbol, 0,
+ 4, this_add_symbol,
this_add_number, 1, NO_RELOC);
/*
- * Now (eg) xOBxxx 1f
- * BRB 2f
- * 1: JMP foo
- * 2:
- */
+ * Now (eg) xOBxxx 1f
+ * BRB 2f
+ * 1: JMP foo
+ * 2:
+ */
}
}
}
p[1] = VAX_JMP;
p[2] = VAX_PC_RELATIVE_MODE;
fix_new (frag_now, p + 3 - frag_now->fr_literal,
- 4, this_add_symbol, 0,
+ 4, this_add_symbol,
this_add_number, 1, NO_RELOC);
}
}
/* All 1-bytes except S^# happen here. */
}
else
- { /* {@}{q^}foo{(Rn)} or S^#foo */
+ {
+ /* {@}{q^}foo{(Rn)} or S^#foo */
if (operandP->vop_reg == -1 && operandP->vop_short != 's')
{
/* "{@}{q^}foo" */
opcode_low_byteP);
know (operandP->vop_mode == 10 + at);
*p = at << 4;
- /* At is the only context we need to carry to */
- /* other side of relax() process. */
- /* Must be in the correct bit position of VAX */
- /* operand spec. byte. */
+ /* At is the only context we need to carry
+ to other side of relax() process. Must
+ be in the correct bit position of VAX
+ operand spec. byte. */
}
else
{
know (length);
know (operandP->vop_short != ' ');
p = frag_more (length + 1);
- /* JF is this array stuff really going to work? */
p[0] = 0xF | ((at + "?\12\14?\16"[length]) << 4);
fix_new (frag_now, p + 1 - frag_now->fr_literal,
- length, this_add_symbol, 0,
+ length, this_add_symbol,
this_add_number, 1, NO_RELOC);
}
}
if (is_undefined)
{
/*
- * We have a SEG_UNKNOWN symbol. It might
- * turn out to be in the same segment as
- * the instruction, permitting relaxation.
- */
+ * We have a SEG_UNKNOWN symbol. It might
+ * turn out to be in the same segment as
+ * the instruction, permitting relaxation.
+ */
p = frag_var (rs_machine_dependent, 5, 2,
ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
this_add_symbol, this_add_number,
md_number_to_chars (p + 1, this_add_number, length);
fix_new (frag_now,
p + 1 - frag_now->fr_literal,
- length, this_add_symbol, 0,
+ length, this_add_symbol,
this_add_number, 1, NO_RELOC);
}
}
}
}
else
- { /* {@}{q^}foo(Rn) or S^# or I^# or # */
+ {
+ /* {@}{q^}foo(Rn) or S^# or I^# or # */
if (operandP->vop_mode < 0xA)
- { /* # or S^# or I^# */
- /* know( (length == 0 && operandP->vop_short == ' ')
- || (length > 0 && operandP->vop_short != ' ')); */
+ {
+ /* # or S^# or I^# */
if (length == 0
&& to_seg == SEG_ABSOLUTE
&& operandP->vop_mode == 8 /* No '@'. */
FRAG_APPEND_1_CHAR (this_add_number);
}
else
- { /* I^#... */
+ {
+ /* I^#... */
know (nbytes);
p = frag_more (nbytes + 1);
know (operandP->vop_reg == 0xF);
if (to_seg == SEG_ABSOLUTE)
{
/*
- * If nbytes > 4, then we are scrod. We don't know if the
- * high order bytes are to be 0xFF or 0x00.
- * BSD4.2 & RMS say use 0x00. OK --- but this
- * assembler needs ANOTHER rewrite to
- * cope properly with this bug.
- */
+ * If nbytes > 4, then we are scrod. We
+ * don't know if the high order bytes
+ * are to be 0xFF or 0x00. BSD4.2 & RMS
+ * say use 0x00. OK --- but this
+ * assembler needs ANOTHER rewrite to
+ * cope properly with this bug. */
md_number_to_chars (p + 1, this_add_number, min (4, nbytes));
if (nbytes > 4)
{
}
else
{
- if (to_seg == SEG_BIG)
+ if (expP->X_op == O_big)
{
/*
- * Problem here is to get the bytes in the right order.
- * We stored our constant as LITTLENUMs, not bytes.
- */
+ * Problem here is to get the bytes
+ * in the right order. We stored
+ * our constant as LITTLENUMs, not
+ * bytes. */
LITTLENUM_TYPE *lP;
lP = floatP->low;
else
{
fix_new (frag_now, p + 1 - frag_now->fr_literal,
- nbytes, this_add_symbol, 0,
+ nbytes, this_add_symbol,
this_add_number, 0, NO_RELOC);
}
}
{
if (to_seg == SEG_ABSOLUTE)
{
- register long test;
+ long test;
test = this_add_number;
else
{
fix_new (frag_now, p + 1 - frag_now->fr_literal,
- length, this_add_symbol, 0,
+ length, this_add_symbol,
this_add_number, 0, NO_RELOC);
}
}
*/
int
md_estimate_size_before_relax (fragP, segment)
- register fragS *fragP;
- register segT segment;
+ fragS *fragP;
+ segT segment;
{
- register char *p;
- register int old_fr_fix;
+ char *p;
+ int old_fr_fix;
old_fr_fix = fragP->fr_fix;
switch (fragP->fr_subtype)
p = fragP->fr_literal + old_fr_fix;
p[0] |= VAX_PC_RELATIVE_MODE; /* Preserve @ bit. */
fragP->fr_fix += 1 + 4;
- fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol, 0,
+ fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
frag_wane (fragP);
}
p[1] = VAX_JMP;
p[2] = VAX_PC_RELATIVE_MODE; /* ...(PC) */
fragP->fr_fix += 1 + 1 + 1 + 4;
- fix_new (fragP, old_fr_fix + 3, 4, fragP->fr_symbol, 0,
+ fix_new (fragP, old_fr_fix + 3, 4, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
frag_wane (fragP);
}
p[4] = VAX_JMP;
p[5] = VAX_PC_RELATIVE_MODE; /* ...(pc) */
fragP->fr_fix += 2 + 2 + 1 + 1 + 4;
- fix_new (fragP, old_fr_fix + 6, 4, fragP->fr_symbol, 0,
+ fix_new (fragP, old_fr_fix + 6, 4, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
frag_wane (fragP);
}
p[3] = VAX_JMP;
p[4] = VAX_PC_RELATIVE_MODE; /* ...(pc) */
fragP->fr_fix += 1 + 2 + 1 + 1 + 4;
- fix_new (fragP, old_fr_fix + 5, 4, fragP->fr_symbol, 0,
+ fix_new (fragP, old_fr_fix + 5, 4, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
frag_wane (fragP);
}
*fragP->fr_opcode += VAX_WIDEN_LONG;
p[0] = VAX_PC_RELATIVE_MODE; /* ...(PC) */
fragP->fr_fix += 1 + 4;
- fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol, 0,
+ fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
frag_wane (fragP);
}
void
md_convert_frag (headers, fragP)
object_headers *headers;
- register fragS *fragP;
+ fragS *fragP;
{
char *addressP; /* -> _var to change. */
char *opcodeP; /* -> opcode char(s) to change. */
relax_addressT segment_address_in_file;
{
/*
- * In: length of relocation (or of address) in chars: 1, 2 or 4.
- * Out: GNU LD relocation length code: 0, 1, or 2.
- */
+ * In: length of relocation (or of address) in chars: 1, 2 or 4.
+ * Out: GNU LD relocation length code: 0, 1, or 2.
+ */
- static unsigned char nbytes_r_length[] =
- {42, 0, 1, 42, 2};
+ static const unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
long r_symbolnum;
know (fixP->fx_addsy != NULL);
where[7] = ((((!S_IS_DEFINED (fixP->fx_addsy)) << 3) & 0x08)
| ((nbytes_r_length[fixP->fx_size] << 1) & 0x06)
| (((fixP->fx_pcrel << 0) & 0x01) & 0x0f));
-
- return;
-} /* tc_aout_fix_to_chars() */
+}
/*
* BUGS, GRIPES, APOLOGIA, etc.
* That is, AFTER we hash it with hash_...(), we want most-used opcodes
* to come out of the hash table faster.
*
- * I am sorry to inflict
- * yet another VAX assembler on the world, but RMS says we must
- * do everything from scratch, to prevent pin-heads restricting
- * this software.
+ * I am sorry to inflict yet another VAX assembler on the world, but
+ * RMS says we must do everything from scratch, to prevent pin-heads
+ * restricting this software.
*/
/*
* source file, and changed the makefile.
*/
-static struct hash_control *op_hash = NULL; /* handle of the OPCODE hash table */
-/* NULL means any use before vip_begin() */
-/* will crash */
+/* handle of the OPCODE hash table */
+static struct hash_control *op_hash;
/*
* In: 1 character, from "bdfghloqpw" being the data-type of an operand
{"jbcc", {"rlvbb?", 0x800000e5}},
{"jbssi", {"rlvbb?", 0x800000e6}},
{"jbcci", {"rlvbb?", 0x800000e7}},
- {"jlbs", {"rlb?", 0x800000e8}}, /* JF changed from rlvbb? */
- {"jlbc", {"rlb?", 0x800000e9}}, /* JF changed from rlvbb? */
+ {"jlbs", {"rlb?", 0x800000e8}},
+ {"jlbc", {"rlb?", 0x800000e9}},
{"jaoblss", {"rlmlb:", 0xC00000f2}},
{"jaobleq", {"rlmlb:", 0xC00000f3}},
- {"jsobgeq", {"mlb:", 0xC00000f4}}, /* JF was rlmlb: */
- {"jsobgtr", {"mlb:", 0xC00000f5}}, /* JF was rlmlb: */
+ {"jsobgeq", {"mlb:", 0xC00000f4}},
+ {"jsobgtr", {"mlb:", 0xC00000f5}},
/* CASEx has no branch addresses in our conception of it. */
/* You should use ".word ..." statements after the "case ...". */
*
* Call me once before you decode any lines.
* I decode votstrs into a hash table at op_hash (which I create).
- * I return an error text: hopefully "".
+ * I return an error text or null.
* If you want, I will include the 'synthetic' jXXX instructions in the
* instruction table.
* You must nominate metacharacters for eg DEC's "#", "@", "^".
*/
-char *
+static const char *
vip_begin (synthetic_too, immediate, indirect, displen)
int synthetic_too; /* 1 means include jXXX op-codes. */
char *immediate, *indirect, *displen;
{
const struct vot *vP; /* scan votstrs */
- char *retval; /* error text */
+ const char *retval = 0; /* error text */
+
+ op_hash = hash_new ();
+
+ for (vP = votstrs; *vP->vot_name && !retval; vP++)
+ retval = hash_insert (op_hash, vP->vot_name, (PTR) &vP->vot_detail);
+
+ if (synthetic_too)
+ for (vP = synthetic_votstrs; *vP->vot_name && !retval; vP++)
+ retval = hash_insert (op_hash, vP->vot_name, (PTR) &vP->vot_detail);
- if ((op_hash = hash_new ()))
- {
- retval = ""; /* OK so far */
- for (vP = votstrs; *vP->vot_name && !*retval; vP++)
- {
- retval = hash_insert (op_hash, vP->vot_name, &vP->vot_detail);
- }
- if (synthetic_too)
- {
- for (vP = synthetic_votstrs; *vP->vot_name && !*retval; vP++)
- {
- retval = hash_insert (op_hash, vP->vot_name, &vP->vot_detail);
- }
- }
- }
- else
- {
- retval = "virtual memory exceeded";
- }
#ifndef CONST_TABLE
vip_op_defaults (immediate, indirect, displen);
#endif
- return (retval);
+ return retval;
}
/*
- * v i p _ e n d ( )
- *
- * Call me once after you have decoded all lines.
- * I do any cleaning-up needed.
- *
- * We don't have to do any cleanup ourselves: all of our operand
- * symbol table is static, and free()ing it is naughty.
- */
-static void
-vip_end ()
-{
-}
-
-/*
* v i p ( )
*
* This converts a string into a vax instruction.
* No argument string should generate such an error string:
* it means a bug in our code, not in the user's text.
*
- * You MUST have called vip_begin() once and vip_end() never before using
- * this function.
+ * You MUST have called vip_begin() once before using this function.
*/
-char * /* "" or bug string */
+static void
vip (vitP, instring)
struct vit *vitP; /* We build an exploded instruction here. */
char *instring; /* Text of a vax instruction: we modify. */
{
- register struct vot_wot *vwP; /* How to bit-encode this opcode. */
- register char *p; /* 1/skip whitespace.2/scan vot_how */
- register char *q; /* */
- register char *bug; /* "" or program logic error */
- register unsigned char count; /* counts number of operands seen */
- register struct vop *operandp;/* scan operands in struct vit */
- register char *alloperr; /* error over all operands */
- register char c; /* Remember char, (we clobber it */
- /* with '\0' temporarily). */
- register vax_opcodeT oc; /* Op-code of this instruction. */
-
- char *vip_op ();
-
- bug = "";
+ /* How to bit-encode this opcode. */
+ struct vot_wot *vwP;
+ /* 1/skip whitespace.2/scan vot_how */
+ char *p;
+ char *q;
+ /* counts number of operands seen */
+ unsigned char count;
+ /* scan operands in struct vit */
+ struct vop *operandp;
+ /* error over all operands */
+ char *alloperr;
+ /* Remember char, (we clobber it with '\0' temporarily). */
+ char c;
+ /* Op-code of this instruction. */
+ vax_opcodeT oc;
+
if (*instring == ' ')
++instring; /* Skip leading whitespace. */
for (p = instring; *p && *p != ' '; p++);; /* MUST end in end-of-string or exactly 1 space. */
instring = p; /* point just past operation code */
alloperr = "";
for (p = vwP->vot_how, operandp = vitP->vit_operand;
- !*alloperr && !*bug && *p;
- operandp++, p += 2
- )
+ !(alloperr && *alloperr) && *p;
+ operandp++, p += 2)
{
/*
* Here to parse one operand. Leave instring pointing just
* past any one ',' that marks the end of this operand.
*/
if (!p[1])
- bug = "p"; /* ODD(!!) number of bytes in vot_how?? */
+ as_fatal ("odd number of bytes in operand description");
else if (*instring)
{
for (q = instring; (c = *q) && c != ','; q++)
operandp->vop_width = p[1];
operandp->vop_nbytes = vax_operand_width_size[p[1]];
operandp->vop_access = p[0];
- bug = vip_op (instring, operandp);
+ vip_op (instring, operandp);
*q = c; /* Restore input text. */
- if (*(operandp->vop_error))
+ if (operandp->vop_error)
alloperr = "Bad operand";
instring = q + (c ? 1 : 0); /* next operand (if any) */
count++; /* won another argument, may have an operr */
}
}
vitP->vit_operands = count;
- return (bug);
}
\f
#ifdef test
char my_indirect[200];
char my_displen[200];
-char *vip ();
-
main ()
{
char *p;
- char *vip_begin ();
printf ("0 means no synthetic instructions. ");
printf ("Value for vip_begin? ");
gets (my_indirect);
printf ("enter displen symbols eg enter ^ ");
gets (my_displen);
- if (*(p = vip_begin (mysynth, my_immediate, my_indirect, my_displen)))
+ if (p = vip_begin (mysynth, my_immediate, my_indirect, my_displen))
{
error ("vip_begin=%s", p);
}
{
break; /* out of for each input text loop */
}
- mybug = vip (&myvit, answer);
- if (*mybug)
- {
- printf ("BUG:\"%s\"\n", mybug);
- }
+ vip (&myvit, answer);
if (*myvit.vit_error)
{
printf ("ERR:\"%s\"\n", myvit.vit_error);
putchar (*p);
}
printf ("\"\n");
- if (*myvop->vop_error)
+ if (myvop->vop_error)
{
printf (" err:\"%s\"\n", myvop->vop_error);
}
- if (*myvop->vop_warn)
+ if (myvop->vop_warn)
{
printf (" wrn:\"%s\"\n", myvop->vop_warn);
}
/* end of vax_ins_parse.c */
-/* JF this used to be a separate file also */
/* vax_reg_parse.c - convert a VAX register name to a number */
/* Copyright (C) 1987 Free Software Foundation, Inc. A part of GNU. */
vax_reg_parse (c1, c2, c3) /* 3 chars of register name */
char c1, c2, c3; /* c3 == 0 if 2-character reg name */
{
- register int retval; /* return -1:15 */
+ int retval; /* return -1:15 */
retval = -1;
*/
-/* vax registers we need to know */
-/* JF #define SP (14) */
-/* JF for one big happy file #define PC (15) */
-
/*
* Because this module is useful for both VMS and UN*X style assemblers
* and because of the variety of UN*X assemblers we must recognise
#define S VIP_INDIRECT,
#define D VIP_DISPLEN,
static const char
- vip_metacharacters[256] =
+vip_metacharacters[256] =
{
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /* ^@ ^A ^B ^C ^D ^E ^F ^G ^H ^I ^J ^K ^L ^M ^N ^O*/
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /* ^P ^Q ^R ^S ^T ^U ^V ^W ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
#else
static char vip_metacharacters[256];
-/* Macro is faster under GCC; The constant table is faster yet, but only works with ASCII */
-#if 0
-static
-#ifdef __GNUC__
- inline
-#endif
static void
vip_op_1 (bit, syms)
int bit;
vip_metacharacters[t] |= bit;
}
-#else
-#define vip_op_1(bit,syms) { \
- unsigned char t; \
- char *table=vip_metacharacters; \
- while(t= *syms++) \
- table[t]|=bit; \
- }
-#endif
-
+/* Can be called any time. More arguments may appear in future. */
static void
-vip_op_defaults (immediate, indirect, displen) /* can be called any time */
- char *immediate; /* Strings of characters for each job. */
+vip_op_defaults (immediate, indirect, displen)
+ char *immediate;
char *indirect;
- char *displen; /* more arguments may appear in future! */
+ char *displen;
{
vip_op_1 (VIP_IMMEDIATE, immediate);
vip_op_1 (VIP_INDIRECT, indirect);
vip_op_1 (VIP_DISPLEN, displen);
-
- return;
}
#endif
* Again, I dare not explain it: just trace ALL the code!
*/
\f
-char * /* (code here) bug message, "" = OK */
-/* our code bug, NOT bad assembly language */
+static void
vip_op (optext, vopP)
/* user's input string e.g.: "@B^foo@bar(AP)[FP]:" */
char *optext;
vop_nbytes : number of bytes in a datum. */
struct vop *vopP;
{
- char *p; /* track operand text forward */
- char *q; /* track operand text backward */
- int at; /* 1 if leading '@' ('*') seen */
- char len; /* one of " bilsw" */
- int hash; /* 1 if leading '#' ('$') seen */
- int sign = 0; /* -1, 0 or +1 */
- int paren = 0; /* 1 if () surround register */
- int reg = 0; /* register number, -1:absent */
- int ndx = 0; /* index register number -1:absent */
- char *bug; /* report any logic error in here, ""==OK */
- char *err; /* report illegal operand, ""==OK */
+ /* track operand text forward */
+ char *p;
+ /* track operand text backward */
+ char *q;
+ /* 1 if leading '@' ('*') seen */
+ int at;
+ /* one of " bilsw" */
+ char len;
+ /* 1 if leading '#' ('$') seen */
+ int hash;
+ /* -1, 0 or +1 */
+ int sign = 0;
+ /* 1 if () surround register */
+ int paren = 0;
+ /* register number, -1:absent */
+ int reg = 0;
+ /* index register number -1:absent */
+ int ndx = 0;
+ /* report illegal operand, ""==OK */
/* " " is a FAKE error: means we won */
/* ANY err that begins with ' ' is a fake. */
/* " " is converted to "" before return */
- char *wrn; /* warn about weird modes pf address */
- char *oldq = NULL; /* preserve q in case we backup */
- int mode = 0; /* build up 4-bit operand mode here */
+ char *err;
+ /* warn about weird modes pf address */
+ char *wrn;
+ /* preserve q in case we backup */
+ char *oldq = NULL;
+ /* build up 4-bit operand mode here */
/* note: index mode is in ndx, this is */
/* the major mode of operand address */
+ int mode = 0;
/*
- * Notice how we move wrong-arg-type bugs INSIDE this module: if we
- * get the types wrong below, we lose at compile time rather than at
- * lint or run time.
- */
+ * Notice how we move wrong-arg-type bugs INSIDE this module: if we
+ * get the types wrong below, we lose at compile time rather than at
+ * lint or run time.
+ */
char access; /* vop_access. */
char width; /* vop_width. */
- int vax_reg_parse (); /* returns 0:15 or -1 if not a register */
-
access = vopP->vop_access;
width = vopP->vop_width;
- bug = /* none of our code bugs (yet) */
- err = /* no user text errors */
- wrn = ""; /* no warnings even */
+ /* None of our code bugs (yet), no user text errors, no warnings
+ even. */
+ err = wrn = 0;
p = optext;
}
/*
- * This code is subtle. It tries to detect all legal (letter)'^'
- * but it doesn't waste time explicitly testing for premature '\0' because
- * this case is rejected as a mismatch against either (letter) or '^'.
- */
+ * This code is subtle. It tries to detect all legal (letter)'^'
+ * but it doesn't waste time explicitly testing for premature '\0' because
+ * this case is rejected as a mismatch against either (letter) or '^'.
+ */
{
- register char c;
+ char c;
c = *p;
if (isupper (c))
p++; /* hash is determined */
/*
- * p points to what may be the beginning of an expression.
- * We have peeled off the front all that is peelable.
- * We know at, len, hash.
- *
- * Lets point q at the end of the text and parse that (backwards).
- */
+ * p points to what may be the beginning of an expression.
+ * We have peeled off the front all that is peelable.
+ * We know at, len, hash.
+ *
+ * Lets point q at the end of the text and parse that (backwards).
+ */
for (q = p; *q; q++)
;
/* run back over *p */
/*
- * As a matter of policy here, we look for [Rn], although both Rn and S^#
- * forbid [Rn]. This is because it is easy, and because only a sick
- * cyborg would have [...] trailing an expression in a VAX-like assembler.
- * A meticulous parser would first check for Rn followed by '(' or '['
- * and not parse a trailing ']' if it found another. We just ban expressions
- * ending in ']'.
- */
+ * As a matter of policy here, we look for [Rn], although both Rn and S^#
+ * forbid [Rn]. This is because it is easy, and because only a sick
+ * cyborg would have [...] trailing an expression in a VAX-like assembler.
+ * A meticulous parser would first check for Rn followed by '(' or '['
+ * and not parse a trailing ']' if it found another. We just ban expressions
+ * ending in ']'.
+ */
if (*q == ']')
{
while (q >= p && *q != '[')
else
ndx = -1;
/*
- * Since we saw a ']' we will demand a register name in the [].
- * If luser hasn't given us one: be rude.
- */
+ * Since we saw a ']' we will demand a register name in the [].
+ * If luser hasn't given us one: be rude.
+ */
if (ndx < 0)
err = "bad register in []";
else if (ndx == PC)
ndx = -1; /* no ']', so no iNDeX register */
/*
- * If err = "..." then we lost: run away.
- * Otherwise ndx == -1 if there was no "[...]".
- * Otherwise, ndx is index register number, and q points before "[...]".
- */
+ * If err = "..." then we lost: run away.
+ * Otherwise ndx == -1 if there was no "[...]".
+ * Otherwise, ndx is index register number, and q points before "[...]".
+ */
\f
if (*q == ' ' && q >= p) /* Expect all whitespace reduced to ' '. */
q--;
/* reverse over whitespace, but don't */
/* run back over *p */
- if (!*err)
+ if (!err || !*err)
{
sign = 0; /* no ()+ or -() seen yet */
* We don't check len. We want a specific error message later if
* user tries "x^...-(Rn)". This is a feature not a bug.
*/
- if (!*err)
+ if (!err || !*err)
{
if (paren && sign < 1)/* !sign is adequate test */
{
* err " " or error message, and other outputs trashed
*/
/* branch operands have restricted forms */
- if (!*err && access == 'b')
+ if ((!err || !*err) && access == 'b')
{
if (at || hash || sign || paren || ndx >= 0 || reg >= 0 || len != ' ')
err = "invalid branch operand";
* ndx -1
* err " " or error message, and other outputs trashed
*/
- if (!*err)
+ if ((!err || !*err) && access == ' ')
{
- if (access == ' ')
- { /* addresses have restricted forms */
- if (at)
- err = "address prohibits @";
+ if (at)
+ err = "address prohibits @";
+ else if (hash)
+ err = "address prohibits #";
+ else if (sign)
+ {
+ if (sign < 0)
+ err = "address prohibits -()";
else
- {
- if (hash)
- err = "address prohibits #";
- else
- {
- if (sign)
- {
- if (sign < 0)
- err = "address prohibits -()";
- else
- err = "address prohibits ()+";
- }
- else
- {
- if (paren)
- err = "address prohibits ()";
- else
- {
- if (ndx >= 0)
- err = "address prohibits []";
- else
- {
- if (reg >= 0)
- err = "address prohibits register";
- else
- {
- if (len != ' ')
- err = "address prohibits displacement length specifier";
- else
- {
- err = " "; /* succeed */
- mode = 0;
- }
- }
- }
- }
- }
- }
- }
+ err = "address prohibits ()+";
+ }
+ else if (paren)
+ err = "address prohibits ()";
+ else if (ndx >= 0)
+ err = "address prohibits []";
+ else if (reg >= 0)
+ err = "address prohibits register";
+ else if (len != ' ')
+ err = "address prohibits displacement length specifier";
+ else
+ {
+ err = " "; /* succeed */
+ mode = 0;
}
}
#endif /*#Ifdef NEVER*/
* exp
* ndx -1
*/
- if (!*err && len == 's')
+ if ((!err || !*err) && len == 's')
{
if (!hash || paren || at || ndx >= 0)
err = "invalid operand of S^#";
reg = 0;
}
/*
- * We have all the expression we will ever get.
- */
+ * We have all the expression we will ever get.
+ */
if (p > q)
err = "S^# needs expression";
else if (access == 'r')
* exp "" enforce empty expression
* ndx optional warn if same as reg
*/
- if (!*err && sign < 0)
+ if ((!err || !*err) && sign < 0)
{
if (len != ' ' || hash || at || p <= q)
err = "invalid operand of -()";
* exp "" enforce empty expression
* ndx optional warn if same as reg
*/
- if (!*err && sign > 0)
+ if ((!err || !*err) && sign > 0)
{
if (len != ' ' || hash || p <= q)
err = "invalid operand of ()+";
* exp
* ndx optional
*/
- if (!*err && hash)
+ if ((!err || !*err) && hash)
{
if (len != 'i' && len != ' ')
err = "# conflicts length";
* exp "" enforce empty expression
* ndx optional warn if same as reg
*/
- if (!*err && !paren && reg >= 0)
+ if ((!err || !*err) && !paren && reg >= 0)
{
if (len != ' ')
err = "length not needed";
}
}
/*
- * If !*err, sign == 0
- * hash == 0
- * paren == 1 OR reg==-1
- */
+ * If !*err, sign == 0
+ * hash == 0
+ * paren == 1 OR reg==-1
+ */
\f
/*
- * Rest of cases fit into one bunch.
- *
- * in: at optional
- * len ' ' or 'b' or 'w' or 'l'
- * hash 0 by program logic
- * p:q expected (empty is not an error)
- * sign 0 by program logic
- * paren optional
- * reg optional
- * ndx optional
- *
- * out: mode 10 + @ + len
- * reg optional
- * len ' ' or 'b' or 'w' or 'l'
- * exp maybe empty
- * ndx optional warn if same as reg
- */
- if (!*err)
+ * Rest of cases fit into one bunch.
+ *
+ * in: at optional
+ * len ' ' or 'b' or 'w' or 'l'
+ * hash 0 by program logic
+ * p:q expected (empty is not an error)
+ * sign 0 by program logic
+ * paren optional
+ * reg optional
+ * ndx optional
+ *
+ * out: mode 10 + @ + len
+ * reg optional
+ * len ' ' or 'b' or 'w' or 'l'
+ * exp maybe empty
+ * ndx optional warn if same as reg
+ */
+ if (!err || !*err)
{
err = " "; /* win (always) */
mode = 10 + (at ? 1 : 0);
*/
if (*err == ' ')
- err = ""; /* " " is no longer an error */
+ err = 0; /* " " is no longer an error */
vopP->vop_mode = mode;
vopP->vop_reg = reg;
vopP->vop_ndx = ndx;
vopP->vop_error = err;
vopP->vop_warn = wrn;
- return (bug);
-
-} /* vip_op() */
+}
\f
/*
main ()
{
- char *vip_op (); /* make cc happy */
-
printf ("enter immediate symbols eg enter # ");
gets (my_immediate);
printf ("enter indirect symbols eg enter @ ");
*ptr++ = 0x17;
*ptr++ = 0x9F;
md_number_to_chars (ptr, offset, 4);
- fix_new (frag, ptr - frag->fr_literal, 4, to_symbol, (symbolS *) 0, (long) 0, 0, NO_RELOC);
+ fix_new (frag, ptr - frag->fr_literal, 4, to_symbol, (long) 0, 0, NO_RELOC);
}
+\f
+#ifdef OBJ_VMS
+CONST char *md_shortopts = "d:STt:V+h:H";
+#else
+CONST char *md_shortopts = "d:STt:V";
+#endif
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
int
-md_parse_option (argP, cntP, vecP)
- char **argP;
- int *cntP;
- char ***vecP;
+md_parse_option (c, arg)
+ int c;
+ char *arg;
{
- char *temp_name; /* name for -t or -d options */
- char opt;
-
- switch (**argP)
+ switch (c)
{
- case 'J':
- /* as_warn ("I can do better than -J!"); */
- break;
-
case 'S':
as_warn ("SYMBOL TABLE not implemented");
- break; /* SYMBOL TABLE not implemented */
+ break;
case 'T':
as_warn ("TOKEN TRACE not implemented");
- break; /* TOKEN TRACE not implemented */
+ break;
case 'd':
- case 't':
- opt = **argP;
- if (**argP)
- { /* Rest of argument is filename. */
- temp_name = *argP;
- while (**argP)
- (*argP)++;
- }
- else if (*cntP)
- {
- while (**argP)
- (*argP)++;
- --(*cntP);
- temp_name = *++(*vecP);
- **vecP = NULL; /* Remember this is not a file-name. */
- }
- else
- {
- as_warn ("I expected a filename after -%c.", opt);
- temp_name = "{absent}";
- }
+ as_warn ("Displacement length %s ignored!", arg);
+ break;
- if (opt == 'd')
- as_warn ("Displacement length %s ignored!", temp_name);
- else
- as_warn ("I don't need or use temp. file \"%s\".", temp_name);
+ case 't':
+ as_warn ("I don't need or use temp. file \"%s\".", arg);
break;
case 'V':
case '+': /* For g++ */
break;
- case '1': /* For backward compatibility */
- break;
-
case 'h': /* No hashing of mixed-case names */
+ {
+ extern char vms_name_mapping;
+ vms_name_mapping = atoi (arg);
+ }
break;
case 'H': /* Show new symbol after hash truncation */
default:
return 0;
-
}
+
return 1;
}
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, "\
+VAX options:\n\
+-d LENGTH ignored\n\
+-J ignored\n\
+-S ignored\n\
+-t FILE ignored\n\
+-T ignored\n\
+-V ignored\n");
+}
+\f
/* We have no need to default values of symbols. */
/* ARGSUSED */
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-#include <stdio.h> /* define stderr */
+#include <stdio.h>
#include <errno.h>
#include "as.h"
extern char *strerror ();
+static void as_show_where PARAMS ((void));
+static void as_warn_internal PARAMS ((char *, unsigned int, char *));
+static void as_bad_internal PARAMS ((char *, unsigned int, char *));
+
/*
* Despite the rest of the comments in this file, (FIXME-SOON),
* here is the current scheme for error messages etc:
* continues as though no error occurred.
*/
-/*
- ERRORS
-
- JF: this is now bogus. We now print more standard error messages
- that try to look like everyone else's.
-
- We print the error message 1st, beginning in column 1.
- All ancillary info starts in column 2 on lines after the
- key error text.
- We try to print a location in logical and physical file
- just after the main error text.
- Caller then prints any appendices after that, begining all
- lines with at least 1 space.
-
- Optionally, we may die.
- There is no need for a trailing '\n' in your error text format
- because we supply one.
-
- as_warn(fmt,args) Like fprintf(stderr,fmt,args) but also call errwhere().
+static void
+identify (file)
+ char *file;
+{
+ static int identified;
+ if (identified)
+ return;
+ identified++;
- as_fatal(fmt,args) Like as_warn() but exit with a fatal status.
+ if (!file)
+ {
+ unsigned int x;
+ as_where (&file, &x);
+ }
- */
+ fprintf (stderr, "%s: Assembler messages:\n", file);
+}
static int warning_count; /* Count of number of warnings issued */
} /* had_errors() */
+/* Print the current location to stderr. */
+
+static void
+as_show_where ()
+{
+ char *file;
+ unsigned int line;
+
+ as_where (&file, &line);
+ identify (file);
+ fprintf (stderr, "%s:%u: ", file, line);
+}
+
/*
* a s _ p e r r o r
*
* Like perror(3), but with more info.
*/
+
void
as_perror (gripe, filename)
- char *gripe; /* Unpunctuated error theme. */
- char *filename;
+ const char *gripe; /* Unpunctuated error theme. */
+ const char *filename;
{
- as_where ();
+ const char *errtxt;
+
+ as_show_where ();
fprintf (stderr, gripe, filename);
- fprintf (stderr, ": %s\n", strerror (errno));
- errno = 0; /* After reporting, clear it. */
-} /* as_perror() */
+#ifdef BFD_ASSEMBLER
+ errtxt = bfd_errmsg (bfd_get_error ());
+#else
+ errtxt = strerror (errno);
+#endif
+ fprintf (stderr, ": %s\n", errtxt);
+ errno = 0;
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_no_error);
+#endif
+}
/*
* a s _ t s k t s k ()
#ifndef NO_STDARG
void
-as_tsktsk (const char *Format,...)
+as_tsktsk (const char *format,...)
{
va_list args;
- as_where ();
- va_start (args, Format);
- vfprintf (stderr, Format, args);
+ as_show_where ();
+ va_start (args, format);
+ vfprintf (stderr, format, args);
va_end (args);
(void) putc ('\n', stderr);
} /* as_tsktsk() */
#else
#ifndef NO_VARARGS
void
-as_tsktsk (Format, va_alist)
- char *Format;
+as_tsktsk (format, va_alist)
+ char *format;
va_dcl
{
va_list args;
- as_where ();
+ as_show_where ();
va_start (args);
- vfprintf (stderr, Format, args);
+ vfprintf (stderr, format, args);
va_end (args);
(void) putc ('\n', stderr);
} /* as_tsktsk() */
#else
/*VARARGS1 */
-as_tsktsk (Format, args)
- char *Format;
+as_tsktsk (format, args)
+ char *format;
{
- as_where ();
- _doprnt (Format, &args, stderr);
+ as_show_where ();
+ _doprnt (format, &args, stderr);
(void) putc ('\n', stderr);
- /* as_where(); */
} /* as_tsktsk */
#endif /* not NO_VARARGS */
#endif /* not NO_STDARG */
+/* The common portion of as_warn and as_warn_where. */
+
+static void
+as_warn_internal (file, line, buffer)
+ char *file;
+ unsigned int line;
+ char *buffer;
+{
+ ++warning_count;
+
+ if (file == NULL)
+ as_where (&file, &line);
+
+ identify (file);
+ fprintf (stderr, "%s:%u: Warning: ", file, line);
+ fputs (buffer, stderr);
+ (void) putc ('\n', stderr);
+#ifndef NO_LISTING
+ listing_warning (buffer);
+#endif
+}
+
/*
* a s _ w a r n ()
*
#ifndef NO_STDARG
void
-as_warn (const char *Format,...)
+as_warn (const char *format,...)
{
va_list args;
char buffer[200];
- if (!flag_suppress_warnings)
+ if (!flagseen['W'])
+ {
+ va_start (args, format);
+ vsprintf (buffer, format, args);
+ va_end (args);
+ as_warn_internal ((char *) NULL, 0, buffer);
+ }
+} /* as_warn() */
+
+#else
+#ifndef NO_VARARGS
+void
+as_warn (format, va_alist)
+ char *format;
+ va_dcl
+{
+ va_list args;
+ char buffer[200];
+
+ if (!flagseen['W'])
+ {
+ va_start (args);
+ vsprintf (buffer, format, args);
+ va_end (args);
+ as_warn_internal ((char *) NULL, 0, buffer);
+ }
+} /* as_warn() */
+
+#else
+/*VARARGS1 */
+as_warn (format, args)
+ char *format;
+{
+ if (!flagseen['W'])
{
++warning_count;
- as_where ();
- va_start (args, Format);
+ as_show_where ();
fprintf (stderr, "Warning: ");
- vsprintf (buffer, Format, args);
- fputs (buffer, stderr);
-#ifndef NO_LISTING
- listing_warning (buffer);
-#endif
- va_end (args);
+ _doprnt (format, &args, stderr);
(void) putc ('\n', stderr);
}
} /* as_warn() */
+#endif /* not NO_VARARGS */
+#endif /* not NO_STDARG */
+
+/* as_warn_where, like as_bad but the file name and line number are
+ passed in. Unfortunately, we have to repeat the function in order
+ to handle the varargs correctly and portably. */
+
+#ifndef NO_STDARG
+void
+as_warn_where (char *file, unsigned int line, const char *format,...)
+{
+ va_list args;
+ char buffer[200];
+
+ if (!flagseen['W'])
+ {
+ va_start (args, format);
+ vsprintf (buffer, format, args);
+ va_end (args);
+ as_warn_internal (file, line, buffer);
+ }
+} /* as_warn() */
+
#else
#ifndef NO_VARARGS
void
-as_warn (Format, va_alist)
- char *Format;
+as_warn_where (file, line, format, va_alist)
+ char *file;
+ unsigned int line;
+ char *format;
va_dcl
{
va_list args;
char buffer[200];
- if (!flag_suppress_warnings)
+ if (!flagseen['W'])
{
- ++warning_count;
- as_where ();
va_start (args);
- fprintf (stderr, "Warning: ");
- vsprintf (buffer, Format, args);
- fputs (buffer, stderr);
-#ifndef NO_LISTING
- listing_warning (buffer);
-#endif
+ vsprintf (buffer, format, args);
va_end (args);
- (void) putc ('\n', stderr);
+ as_warn_internal (file, line, buffer);
}
} /* as_warn() */
#else
/*VARARGS1 */
-as_warn (Format, args)
- char *Format;
+as_warn_where (file, line, format, args)
+ char *file;
+ unsigned int line;
+ char *format;
{
- if (!flag_suppress_warnings)
+ if (!flagseen['W'])
{
++warning_count;
- as_where ();
- _doprnt (Format, &args, stderr);
+ identify (file);
+ fprintf (stderr, "%s:%u: Warning: ", file, line);
+ _doprnt (format, &args, stderr);
(void) putc ('\n', stderr);
- /* as_where(); */
}
} /* as_warn() */
#endif /* not NO_VARARGS */
#endif /* not NO_STDARG */
+/* The common portion of as_bad and as_bad_where. */
+
+static void
+as_bad_internal (file, line, buffer)
+ char *file;
+ unsigned int line;
+ char *buffer;
+{
+ ++error_count;
+
+ if (file == NULL)
+ as_where (&file, &line);
+
+ identify (file);
+ fprintf (stderr, "%s:%u: Error: ", file, line);
+ fputs (buffer, stderr);
+ (void) putc ('\n', stderr);
+#ifndef NO_LISTING
+ listing_error (buffer);
+#endif
+}
+
/*
* a s _ b a d ()
*
#ifndef NO_STDARG
void
-as_bad (const char *Format,...)
+as_bad (const char *format,...)
{
va_list args;
char buffer[200];
- ++error_count;
- as_where ();
- va_start (args, Format);
- fprintf (stderr, "Error: ");
+ va_start (args, format);
+ vsprintf (buffer, format, args);
+ va_end (args);
- vsprintf (buffer, Format, args);
- fputs (buffer, stderr);
-#ifndef NO_LISTING
- listing_error (buffer);
-#endif
+ as_bad_internal ((char *) NULL, 0, buffer);
+}
+
+#else
+#ifndef NO_VARARGS
+void
+as_bad (format, va_alist)
+ char *format;
+ va_dcl
+{
+ va_list args;
+ char buffer[200];
+
+ va_start (args);
+ vsprintf (buffer, format, args);
va_end (args);
+
+ as_bad_internal ((char *) NULL, 0, buffer);
+}
+
+#else
+/*VARARGS1 */
+as_bad (format, args)
+ char *format;
+{
+ ++error_count;
+
+ as_show_where ();
+ fprintf (stderr, "Error: ");
+ _doprnt (format, &args, stderr);
(void) putc ('\n', stderr);
} /* as_bad() */
+#endif /* not NO_VARARGS */
+#endif /* not NO_STDARG */
+
+/* as_bad_where, like as_bad but the file name and line number are
+ passed in. Unfortunately, we have to repeat the function in order
+ to handle the varargs correctly and portably. */
+
+#ifndef NO_STDARG
+void
+as_bad_where (char *file, unsigned int line, const char *format,...)
+{
+ va_list args;
+ char buffer[200];
+
+ va_start (args, format);
+ vsprintf (buffer, format, args);
+ va_end (args);
+
+ as_bad_internal (file, line, buffer);
+}
+
#else
#ifndef NO_VARARGS
void
-as_bad (Format, va_alist)
- char *Format;
+as_bad_where (file, line, format, va_alist)
+ char *file;
+ unsigned int line;
+ char *format;
va_dcl
{
va_list args;
char buffer[200];
- ++error_count;
- as_where ();
va_start (args);
- vsprintf (buffer, Format, args);
- fputs (buffer, stderr);
-#ifndef NO_LISTING
- listing_error (buffer);
-#endif
-
+ vsprintf (buffer, format, args);
va_end (args);
- (void) putc ('\n', stderr);
-} /* as_bad() */
+
+ as_bad_internal (file, line, buffer);
+}
#else
/*VARARGS1 */
-as_bad (Format, args)
- char *Format;
+as_bad_where (file, line, format, args)
+ char *file;
+ unsigned int line;
+ char *format;
{
++error_count;
- as_where ();
- fprintf (stderr, "Error: ");
- _doprnt (Format, &args, stderr);
+ identify (file);
+ fprintf (stderr, "%s:%u: Error: ", file, line);
+ _doprnt (format, &args, stderr);
(void) putc ('\n', stderr);
- /* as_where(); */
} /* as_bad() */
#endif /* not NO_VARARGS */
#ifndef NO_STDARG
void
-as_fatal (const char *Format,...)
+as_fatal (const char *format,...)
{
va_list args;
- as_where ();
- va_start (args, Format);
- fprintf (stderr, "Assembler fatal error:");
- vfprintf (stderr, Format, args);
+ as_show_where ();
+ va_start (args, format);
+ fprintf (stderr, "Fatal error:");
+ vfprintf (stderr, format, args);
(void) putc ('\n', stderr);
va_end (args);
exit (33);
#else
#ifndef NO_VARARGS
void
-as_fatal (Format, va_alist)
- char *Format;
+as_fatal (format, va_alist)
+ char *format;
va_dcl
{
va_list args;
- as_where ();
+ as_show_where ();
va_start (args);
- fprintf (stderr, "Assembler fatal error:");
- vfprintf (stderr, Format, args);
+ fprintf (stderr, "Fatal error:");
+ vfprintf (stderr, format, args);
(void) putc ('\n', stderr);
va_end (args);
exit (33);
#else
/*VARARGS1 */
-as_fatal (Format, args)
- char *Format;
+as_fatal (format, args)
+ char *format;
{
- as_where ();
- fprintf (stderr, "Assembler fatal error:");
- _doprnt (Format, &args, stderr);
+ as_show_where ();
+ fprintf (stderr, "Fatal error:");
+ _doprnt (format, &args, stderr);
(void) putc ('\n', stderr);
- /* as_where(); */
exit (33); /* What is a good exit status? */
} /* as_fatal() */