summaryrefslogtreecommitdiff
path: root/gnu/usr.bin
diff options
context:
space:
mode:
authorcgd <cgd@NetBSD.org>1993-05-13 14:48:19 +0000
committercgd <cgd@NetBSD.org>1993-05-13 14:48:19 +0000
commitf8d29a33fcbb1a0031582def19f5c3c6a71dcda5 (patch)
tree7b79a3064edf400f067784a3b4ceda6f58d391d8 /gnu/usr.bin
parent767fcb4410051ffcac827d87a3698c15d5b0ab33 (diff)
add gas config files from net/2
Diffstat (limited to 'gnu/usr.bin')
-rw-r--r--gnu/usr.bin/gas/config/Makefile.hp3004
-rw-r--r--gnu/usr.bin/gas/config/Makefile.vax3
-rw-r--r--gnu/usr.bin/gas/config/atof-vax.c513
-rw-r--r--gnu/usr.bin/gas/config/i860-opcode.h491
-rw-r--r--gnu/usr.bin/gas/config/i860.c1142
-rw-r--r--gnu/usr.bin/gas/config/i860.h48
-rw-r--r--gnu/usr.bin/gas/config/m-hpux.h24
-rw-r--r--gnu/usr.bin/gas/config/m-sun3.h31
-rw-r--r--gnu/usr.bin/gas/config/m68k-opcode.h1680
-rw-r--r--gnu/usr.bin/gas/config/m68k.c3540
-rw-r--r--gnu/usr.bin/gas/config/m68k.h20
-rw-r--r--gnu/usr.bin/gas/config/ns32k-opcode.h434
-rw-r--r--gnu/usr.bin/gas/config/ns32k.c1768
-rw-r--r--gnu/usr.bin/gas/config/sparc-opcode.h636
-rw-r--r--gnu/usr.bin/gas/config/sparc.c1285
-rw-r--r--gnu/usr.bin/gas/config/sparc.h52
-rw-r--r--gnu/usr.bin/gas/config/vax-inst.h77
-rw-r--r--gnu/usr.bin/gas/config/vax-opcode.h382
-rw-r--r--gnu/usr.bin/gas/config/vax.c3364
19 files changed, 15494 insertions, 0 deletions
diff --git a/gnu/usr.bin/gas/config/Makefile.hp300 b/gnu/usr.bin/gas/config/Makefile.hp300
new file mode 100644
index 00000000000..16ca9bddcc4
--- /dev/null
+++ b/gnu/usr.bin/gas/config/Makefile.hp300
@@ -0,0 +1,4 @@
+# @(#)Makefile.hp300 6.1 (Berkeley) 3/3/91
+
+CFLAGS+= -Dm68851
+SRCS+= m68k.c atof-ieee.c
diff --git a/gnu/usr.bin/gas/config/Makefile.vax b/gnu/usr.bin/gas/config/Makefile.vax
new file mode 100644
index 00000000000..1230e4b578a
--- /dev/null
+++ b/gnu/usr.bin/gas/config/Makefile.vax
@@ -0,0 +1,3 @@
+# @(#)Makefile.vax 6.1 (Berkeley) 3/3/91
+
+SRCS+= vax.c atof-vax.c
diff --git a/gnu/usr.bin/gas/config/atof-vax.c b/gnu/usr.bin/gas/config/atof-vax.c
new file mode 100644
index 00000000000..cd343ba4ce0
--- /dev/null
+++ b/gnu/usr.bin/gas/config/atof-vax.c
@@ -0,0 +1,513 @@
+/* atof_vax.c - turn a Flonum into a VAX floating point number
+ Copyright (C) 1987 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+ /* JF added these two for md_atof() */
+#include "as.h"
+#include "read.h"
+
+#include "flonum.h"
+
+
+ /* Precision in LittleNums. */
+#define MAX_PRECISION (8)
+#define H_PRECISION (8)
+#define G_PRECISION (4)
+#define D_PRECISION (4)
+#define F_PRECISION (2)
+
+ /* Length in LittleNums of guard bits. */
+#define GUARD (2)
+
+int /* Number of chars in flonum type 'letter'. */
+atof_vax_sizeof (letter)
+ char letter;
+{
+ int return_value;
+
+ /*
+ * Permitting uppercase letters is probably a bad idea.
+ * Please use only lower-cased letters in case the upper-cased
+ * ones become unsupported!
+ */
+ switch (letter)
+ {
+ case 'f':
+ case 'F':
+ return_value = 4;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'g':
+ case 'G':
+ return_value = 8;
+ break;
+
+ case 'h':
+ case 'H':
+ return_value = 16;
+ break;
+
+ default:
+ return_value = 0;
+ break;
+ }
+ return (return_value);
+} /* atof_vax_sizeof */
+
+static const long int mask [] = {
+ 0x00000000,
+ 0x00000001,
+ 0x00000003,
+ 0x00000007,
+ 0x0000000f,
+ 0x0000001f,
+ 0x0000003f,
+ 0x0000007f,
+ 0x000000ff,
+ 0x000001ff,
+ 0x000003ff,
+ 0x000007ff,
+ 0x00000fff,
+ 0x00001fff,
+ 0x00003fff,
+ 0x00007fff,
+ 0x0000ffff,
+ 0x0001ffff,
+ 0x0003ffff,
+ 0x0007ffff,
+ 0x000fffff,
+ 0x001fffff,
+ 0x003fffff,
+ 0x007fffff,
+ 0x00ffffff,
+ 0x01ffffff,
+ 0x03ffffff,
+ 0x07ffffff,
+ 0x0fffffff,
+ 0x1fffffff,
+ 0x3fffffff,
+ 0x7fffffff,
+ 0xffffffff
+ };
+
+
+/* Shared between flonum_gen2vax and next_bits */
+static int bits_left_in_littlenum;
+static LITTLENUM_TYPE * littlenum_pointer;
+static LITTLENUM_TYPE * littlenum_end;
+
+static int
+next_bits (number_of_bits)
+ int number_of_bits;
+{
+ int return_value;
+
+ if(littlenum_pointer<littlenum_end)
+ return 0;
+ if (number_of_bits >= bits_left_in_littlenum)
+ {
+ return_value = mask [bits_left_in_littlenum] & * littlenum_pointer;
+ number_of_bits -= bits_left_in_littlenum;
+ return_value <<= number_of_bits;
+ bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
+ littlenum_pointer --;
+ if(littlenum_pointer>=littlenum_end)
+ return_value |= ( (* littlenum_pointer) >> (bits_left_in_littlenum) ) & mask [number_of_bits];
+ }
+ else
+ {
+ bits_left_in_littlenum -= number_of_bits;
+ return_value = mask [number_of_bits] & ( (* littlenum_pointer) >> bits_left_in_littlenum);
+ }
+ return (return_value);
+}
+
+static void
+make_invalid_floating_point_number (words)
+ LITTLENUM_TYPE * words;
+{
+ * words = 0x8000; /* Floating Reserved Operand Code */
+}
+
+static int /* 0 means letter is OK. */
+what_kind_of_float (letter, precisionP, exponent_bitsP)
+ char letter; /* In: lowercase please. What kind of float? */
+ int * precisionP; /* Number of 16-bit words in the float. */
+ long int * exponent_bitsP; /* Number of exponent bits. */
+{
+ int retval; /* 0: OK. */
+
+ retval = 0;
+ switch (letter)
+ {
+ case 'f':
+ * precisionP = F_PRECISION;
+ * exponent_bitsP = 8;
+ break;
+
+ case 'd':
+ * precisionP = D_PRECISION;
+ * exponent_bitsP = 8;
+ break;
+
+ case 'g':
+ * precisionP = G_PRECISION;
+ * exponent_bitsP = 11;
+ break;
+
+ case 'h':
+ * precisionP = H_PRECISION;
+ * exponent_bitsP = 15;
+ break;
+
+ default:
+ retval = 69;
+ break;
+ }
+ return (retval);
+}
+
+/***********************************************************************\
+* *
+* Warning: this returns 16-bit LITTLENUMs, because that is *
+* what the VAX thinks in. It is up to the caller to figure *
+* out any alignment problems and to conspire for the bytes/word *
+* to be emitted in the right order. Bigendians beware! *
+* *
+\***********************************************************************/
+
+char * /* Return pointer past text consumed. */
+atof_vax (str, what_kind, words)
+ char * str; /* Text to convert to binary. */
+ char what_kind; /* 'd', 'f', 'g', 'h' */
+ LITTLENUM_TYPE * words; /* Build the binary here. */
+{
+ FLONUM_TYPE f;
+ LITTLENUM_TYPE bits [MAX_PRECISION + MAX_PRECISION + GUARD];
+ /* Extra bits for zeroed low-order bits. */
+ /* The 1st MAX_PRECISION are zeroed, */
+ /* the last contain flonum bits. */
+ char * return_value;
+ int precision; /* Number of 16-bit words in the format. */
+ long int exponent_bits;
+
+ return_value = str;
+ f . low = bits + MAX_PRECISION;
+ f . high = NULL;
+ f . leader = NULL;
+ f . exponent = NULL;
+ f . sign = '\0';
+
+ if (what_kind_of_float (what_kind, & precision, & exponent_bits))
+ {
+ return_value = NULL; /* We lost. */
+ make_invalid_floating_point_number (words);
+ }
+ if (return_value)
+ {
+ bzero (bits, sizeof(LITTLENUM_TYPE) * MAX_PRECISION);
+
+ /* Use more LittleNums than seems */
+ /* necessary: the highest flonum may have */
+ /* 15 leading 0 bits, so could be useless. */
+ f . high = f . low + precision - 1 + GUARD;
+
+ if (atof_generic (& return_value, ".", "eE", & f))
+ {
+ make_invalid_floating_point_number (words);
+ return_value = NULL; /* we lost */
+ }
+ else
+ {
+ if (flonum_gen2vax (what_kind, & f, words))
+ {
+ return_value = NULL;
+ }
+ }
+ }
+ return (return_value);
+}
+
+/*
+ * In: a flonum, a vax floating point format.
+ * Out: a vax floating-point bit pattern.
+ */
+
+int /* 0: OK. */
+flonum_gen2vax (format_letter, f, words)
+ char format_letter; /* One of 'd' 'f' 'g' 'h'. */
+ FLONUM_TYPE * f;
+ LITTLENUM_TYPE * words; /* Deliver answer here. */
+{
+ LITTLENUM_TYPE * lp;
+ int precision;
+ long int exponent_bits;
+ int return_value; /* 0 == OK. */
+
+ return_value = what_kind_of_float (format_letter, & precision, & exponent_bits);
+ if (return_value != 0)
+ {
+ make_invalid_floating_point_number (words);
+ }
+ else
+ {
+ if (f -> low > f -> leader)
+ {
+ /* 0.0e0 seen. */
+ bzero (words, sizeof(LITTLENUM_TYPE) * precision);
+ }
+ else
+ {
+ long int exponent_1;
+ long int exponent_2;
+ long int exponent_3;
+ long int exponent_4;
+ int exponent_skippage;
+ LITTLENUM_TYPE word1;
+
+ /* JF: Deal with new Nan, +Inf and -Inf codes */
+ if(f->sign!='-' && f->sign!='+') {
+ make_invalid_floating_point_number(words);
+ return return_value;
+ }
+ /*
+ * All vaxen floating_point formats (so far) have:
+ * Bit 15 is sign bit.
+ * Bits 14:n are excess-whatever exponent.
+ * Bits n-1:0 (if any) are most significant bits of fraction.
+ * Bits 15:0 of the next word are the next most significant bits.
+ * And so on for each other word.
+ *
+ * All this to be compatible with a KF11?? (Which is still faster
+ * than lots of vaxen I can think of, but it also has higher
+ * maintenance costs ... sigh).
+ *
+ * So we need: number of bits of exponent, number of bits of
+ * mantissa.
+ */
+
+#ifdef NEVER /******* This zeroing seems redundant - Dean 3may86 **********/
+ /*
+ * No matter how few bits we got back from the atof()
+ * routine, add enough zero littlenums so the rest of the
+ * code won't run out of "significant" bits in the mantissa.
+ */
+ {
+ LITTLENUM_TYPE * ltp;
+ for (ltp = f -> leader + 1;
+ ltp <= f -> low + precision;
+ ltp ++)
+ {
+ * ltp = 0;
+ }
+ }
+#endif
+
+ bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
+ littlenum_pointer = f -> leader;
+ littlenum_end = f->low;
+ /* Seek (and forget) 1st significant bit */
+ for (exponent_skippage = 0;
+ ! next_bits(1);
+ exponent_skippage ++)
+ {
+ }
+ exponent_1 = f -> exponent + f -> leader + 1 - f -> low;
+ /* Radix LITTLENUM_RADIX, point just higher than f -> leader. */
+ exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
+ /* Radix 2. */
+ exponent_3 = exponent_2 - exponent_skippage;
+ /* Forget leading zeros, forget 1st bit. */
+ exponent_4 = exponent_3 + (1 << (exponent_bits - 1));
+ /* Offset exponent. */
+
+ if (exponent_4 & ~ mask [exponent_bits])
+ {
+ /*
+ * Exponent overflow. Lose immediately.
+ */
+
+ make_invalid_floating_point_number (words);
+
+ /*
+ * We leave return_value alone: admit we read the
+ * number, but return a floating exception
+ * because we can't encode the number.
+ */
+ }
+ else
+ {
+ lp = words;
+
+ /* Word 1. Sign, exponent and perhaps high bits. */
+ /* Assume 2's complement integers. */
+ word1 = ((exponent_4 & mask [exponent_bits]) << (15 - exponent_bits))
+ | ((f -> sign == '+') ? 0 : 0x8000)
+ | next_bits (15 - exponent_bits);
+ * lp ++ = word1;
+
+ /* The rest of the words are just mantissa bits. */
+ for (; lp < words + precision; lp++)
+ {
+ * lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
+ }
+
+ if (next_bits (1))
+ {
+ /*
+ * Since the NEXT bit is a 1, round UP the mantissa.
+ * The cunning design of these hidden-1 floats permits
+ * us to let the mantissa overflow into the exponent, and
+ * it 'does the right thing'. However, we lose if the
+ * highest-order bit of the lowest-order word flips.
+ * Is that clear?
+ */
+
+ unsigned long int carry;
+
+ /*
+ #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
+ Please allow at least 1 more bit in carry than is in a LITTLENUM.
+ We need that extra bit to hold a carry during a LITTLENUM carry
+ propagation. Another extra bit (kept 0) will assure us that we
+ don't get a sticky sign bit after shifting right, and that
+ permits us to propagate the carry without any masking of bits.
+ #endif
+ */
+ for (carry = 1, lp --;
+ carry && (lp >= words);
+ lp --)
+ {
+ carry = * lp + carry;
+ * lp = carry;
+ carry >>= LITTLENUM_NUMBER_OF_BITS;
+ }
+
+ if ( (word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)) )
+ {
+ make_invalid_floating_point_number (words);
+ /*
+ * We leave return_value alone: admit we read the
+ * number, but return a floating exception
+ * because we can't encode the number.
+ */
+ }
+ } /* if (we needed to round up) */
+ } /* if (exponent overflow) */
+ } /* if (0.0e0) */
+ } /* if (float_type was OK) */
+ return (return_value);
+}
+
+
+/* JF this used to be in vax.c but this looks like a better place for it */
+
+/*
+ * md_atof()
+ *
+ * In: input_line_pointer -> the 1st character of a floating-point
+ * number.
+ * 1 letter denoting the type of statement that wants a
+ * binary floating point number returned.
+ * Address of where to build floating point literal.
+ * Assumed to be 'big enough'.
+ * Address of where to return size of literal (in chars).
+ *
+ * Out: Input_line_pointer -> of next char after floating number.
+ * Error message, or "".
+ * Floating point literal.
+ * Number of chars we used for the literal.
+ */
+
+int atof_vax_sizeof();
+
+#define MAXIMUM_NUMBER_OF_LITTLENUMS (8) /* For .hfloats. */
+
+char *
+md_atof (what_statement_type, literalP, sizeP)
+ char what_statement_type;
+ char * literalP;
+ int * sizeP;
+{
+ LITTLENUM_TYPE words [MAXIMUM_NUMBER_OF_LITTLENUMS];
+ register char kind_of_float;
+ register int number_of_chars;
+ register LITTLENUM_TYPE * littlenum_pointer;
+
+ switch (what_statement_type)
+ {
+ case 'F': /* .float */
+ case 'f': /* .ffloat */
+ kind_of_float = 'f';
+ break;
+
+ case 'D': /* .double */
+ case 'd': /* .dfloat */
+ kind_of_float = 'd';
+ break;
+
+ case 'g': /* .gfloat */
+ kind_of_float = 'g';
+ break;
+
+ case 'h': /* .hfloat */
+ kind_of_float = 'h';
+ break;
+
+ default:
+ kind_of_float = 0;
+ break;
+ };
+
+ if (kind_of_float)
+ {
+ register LITTLENUM_TYPE * limit;
+ char * atof_vax();
+
+ input_line_pointer = atof_vax (input_line_pointer,
+ kind_of_float,
+ words);
+ /*
+ * The atof_vax() builds up 16-bit numbers.
+ * Since the assembler may not be running on
+ * a little-endian machine, be very careful about
+ * converting words to chars.
+ */
+ number_of_chars = atof_vax_sizeof (kind_of_float);
+ know( number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof(LITTLENUM_TYPE) );
+ limit = words + (number_of_chars / sizeof(LITTLENUM_TYPE));
+ for (littlenum_pointer = words;
+ littlenum_pointer < limit;
+ littlenum_pointer ++)
+ {
+ md_number_to_chars (literalP, * littlenum_pointer, sizeof(LITTLENUM_TYPE));
+ literalP += sizeof(LITTLENUM_TYPE);
+ };
+ }
+ else
+ {
+ number_of_chars = 0;
+ };
+
+ * sizeP = number_of_chars;
+ return (kind_of_float ? "" : "Bad call to md_atof()");
+} /* md_atof() */
+
+/* atof_vax.c */
diff --git a/gnu/usr.bin/gas/config/i860-opcode.h b/gnu/usr.bin/gas/config/i860-opcode.h
new file mode 100644
index 00000000000..18336da4d32
--- /dev/null
+++ b/gnu/usr.bin/gas/config/i860-opcode.h
@@ -0,0 +1,491 @@
+/* Table of opcodes for the i860.
+ Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler, and GDB, the GNU disassembler.
+
+GAS/GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS/GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS or GDB; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined(__STDC__) && !defined(const)
+#define const
+#endif
+
+/*
+ * Structure of an opcode table entry.
+ */
+struct i860_opcode
+{
+ const char *name;
+ unsigned long int match; /* Bits that must be set. */
+ unsigned long int lose; /* Bits that must not be set. */
+ const char *args;
+ /* Nonzero if this is a possible expand-instruction. */
+ char expand;
+};
+
+enum expand_type
+{
+ E_MOV = 1, E_ADDR, E_U32, E_AND, E_S32, E_DELAY
+};
+
+/*
+ All i860 opcodes are 32 bits, except for the pseudoinstructions
+ and the operations utilizing a 32-bit address expression, an
+ unsigned 32-bit constant, or a signed 32-bit constant.
+ These opcodes are expanded into a two-instruction sequence for
+ any situation where the immediate operand does not fit in 32 bits.
+ In the case of the add and subtract operations the expansion is
+ to a three-instruction sequence (ex: orh, or, adds). In cases
+ where the address is to be relocated, the instruction is
+ expanded to handle the worse case, this could be optimized at
+ the final link if the actual address were known.
+
+ The pseudoinstructions are: mov, fmov, pmov, nop, and fnop.
+ These instructions are implemented as a one or two instruction
+ sequence of other operations.
+
+ The match component is a mask saying which bits must match a
+ particular opcode in order for an instruction to be an instance
+ of that opcode.
+
+ The args component is a string containing one character
+ for each operand of the instruction.
+
+Kinds of operands:
+ # Number used by optimizer. It is ignored.
+ 1 src1 integer register.
+ 2 src2 integer register.
+ d dest register.
+ c ctrlreg control register.
+ i 16 bit immediate.
+ I 16 bit immediate, aligned.
+ 5 5 bit immediate.
+ l lbroff 26 bit PC relative immediate.
+ r sbroff 16 bit PC relative immediate.
+ s split 16 bit immediate.
+ S split 16 bit immediate, aligned.
+ e src1 floating point register.
+ f src2 floating point register.
+ g dest floating point register.
+
+*/
+
+/* The order of the opcodes in this table is significant:
+
+ * The assembler requires that all instances of the same mnemonic must be
+ consecutive. If they aren't, the assembler will bomb at runtime.
+
+ * The disassembler should not care about the order of the opcodes. */
+
+static struct i860_opcode i860_opcodes[] =
+{
+
+/* REG-Format Instructions */
+{ "ld.c", 0x30000000, 0xcc000000, "c,d", 0 }, /* ld.c csrc2,idest */
+{ "ld.b", 0x00000000, 0xfc000000, "1(2),d", 0 }, /* ld.b isrc1(isrc2),idest */
+{ "ld.b", 0x04000000, 0xf8000000, "I(2),d", E_ADDR }, /* ld.b #const(isrc2),idest */
+{ "ld.s", 0x10000000, 0xec000001, "1(2),d", 0 }, /* ld.s isrc1(isrc2),idest */
+{ "ld.s", 0x14000001, 0xe8000000, "I(2),d", E_ADDR }, /* ld.s #const(isrc2),idest */
+{ "ld.l", 0x10000001, 0xec000000, "1(2),d", 0 }, /* ld.l isrc1(isrc2),idest */
+{ "ld.l", 0x14000001, 0xe8000000, "I(2),d", E_ADDR }, /* ld.l #const(isrc2),idest */
+
+{ "st.c", 0x38000000, 0xc4000000, "1,c", 0 }, /* st.c isrc1ni,csrc2 */
+{ "st.b", 0x0c000000, 0xf0000000, "1,S(2)", E_ADDR }, /* st.b isrc1ni,#const(isrc2) */
+{ "st.s", 0x1c000000, 0xe0000000, "1,S(2)", E_ADDR }, /* st.s isrc1ni,#const(isrc2) */
+{ "st.l", 0x1c000001, 0xe0000000, "1,S(2)", E_ADDR }, /* st.l isrc1ni,#const(isrc2) */
+
+{ "ixfr", 0x08000000, 0xf4000000, "1,g", 0 }, /* ixfr isrc1ni,fdest */
+
+{ "fld.l", 0x20000002, 0xdc000001, "1(2),g", 0 }, /* fld.l isrc1(isrc2),fdest */
+{ "fld.l", 0x24000002, 0xd8000001, "i(2),g", E_ADDR }, /* fld.l #const(isrc2),fdest */
+{ "fld.l", 0x20000003, 0xdc000000, "1(2)++,g", 0 }, /* fld.l isrc1(isrc2)++,fdest */
+{ "fld.l", 0x24000003, 0xd8000000, "i(2)++,g", E_ADDR }, /* fld.l #const(isrc2)++,fdest */
+{ "fld.d", 0x20000000, 0xdc000007, "1(2),g", 0 }, /* fld.d isrc1(isrc2),fdest */
+{ "fld.d", 0x24000000, 0xd8000007, "i(2),g", E_ADDR }, /* fld.d #const(isrc2),fdest */
+{ "fld.d", 0x20000001, 0xdc000006, "1(2)++,g", 0 }, /* fld.d isrc1(isrc2)++,fdest */
+{ "fld.d", 0x24000001, 0xd8000006, "i(2)++,g", E_ADDR }, /* fld.d #const(isrc2)++,fdest */
+{ "fld.q", 0x20000004, 0xdc000003, "1(2),g", 0 }, /* fld.q isrc1(isrc2),fdest */
+{ "fld.q", 0x24000004, 0xd8000003, "i(2),g", E_ADDR }, /* fld.q #const(isrc2),fdest */
+{ "fld.q", 0x20000005, 0xdc000002, "1(2)++,g", 0 }, /* fld.q isrc1(isrc2)++,fdest */
+{ "fld.q", 0x24000005, 0xd8000002, "i(2)++,g", E_ADDR }, /* fld.q #const(isrc2)++,fdest */
+
+{ "pfld.l", 0x60000000, 0x9c000003, "1(2),g", 0 }, /* pfld.l isrc1(isrc2),fdest */
+{ "pfld.l", 0x64000000, 0x98000003, "i(2),g", E_ADDR }, /* pfld.l #const(isrc2),fdest */
+{ "pfld.l", 0x60000001, 0x9c000002, "1(2)++,g", 0 }, /* pfld.l isrc1(isrc2)++,fdest */
+{ "pfld.l", 0x64000001, 0x98000002, "i(2)++,g", E_ADDR }, /* pfld.l #const(isrc2)++,fdest */
+{ "pfld.d", 0x60000000, 0x9c000007, "1(2),g", 0 }, /* pfld.d isrc1(isrc2),fdest */
+{ "pfld.d", 0x64000000, 0x98000007, "i(2),g", E_ADDR }, /* pfld.d #const(isrc2),fdest */
+{ "pfld.d", 0x60000001, 0x9c000006, "1(2)++,g", 0 }, /* pfld.d isrc1(isrc2)++,fdest */
+{ "pfld.d", 0x64000001, 0x98000006, "i(2)++,g", E_ADDR }, /* pfld.d #const(isrc2)++,fdest */
+
+{ "fst.l", 0x28000002, 0xd4000001, "g,1(2)", 0 }, /* fst.l fdest,isrc1(isrc2) */
+{ "fst.l", 0x2c000002, 0xd0000001, "g,i(2)", E_ADDR }, /* fst.l fdest,#const(isrc2) */
+{ "fst.l", 0x28000003, 0xd4000000, "g,1(2)++", 0 }, /* fst.l fdest,isrc1(isrc2)++ */
+{ "fst.l", 0x2c000003, 0xd0000000, "g,i(2)++", E_ADDR }, /* fst.l fdest,#const(isrc2)++ */
+{ "fst.d", 0x28000000, 0xd4000007, "g,1(2)", 0 }, /* fst.d fdest,isrc1(isrc2) */
+{ "fst.d", 0x2c000000, 0xd0000007, "g,i(2)", E_ADDR }, /* fst.d fdest,#const(isrc2) */
+{ "fst.d", 0x28000001, 0xd4000006, "g,1(2)++", 0 }, /* fst.d fdest,isrc1(isrc2)++ */
+{ "fst.d", 0x2c000001, 0xd0000006, "g,i(2)++", E_ADDR }, /* fst.d fdest,#const(isrc2)++ */
+
+{ "pst.d", 0x3c000000, 0xc0000007, "g,i(2)", E_ADDR }, /* pst.d fdest,#const(isrc2) */
+{ "pst.d", 0x3c000001, 0xc0000006, "g,i(2)++", E_ADDR }, /* pst.d fdest,#const(isrc2)++ */
+
+{ "addu", 0x80000000, 0x7c000000, "1,2,d", 0 }, /* addu isrc1,isrc2,idest */
+{ "addu", 0x84000000, 0x78000000, "i,2,d", E_S32 }, /* addu #const,isrc2,idest */
+{ "adds", 0x90000000, 0x6c000000, "1,2,d", 0 }, /* adds isrc1,isrc2,idest */
+{ "adds", 0x94000000, 0x68000000, "i,2,d", E_S32 }, /* adds #const,isrc2,idest */
+{ "subu", 0x88000000, 0x74000000, "1,2,d", 0 }, /* subu isrc1,isrc2,idest */
+{ "subu", 0x8c000000, 0x70000000, "i,2,d", E_S32 }, /* subu #const,isrc2,idest */
+{ "subs", 0x98000000, 0x64000000, "1,2,d", 0 }, /* subs isrc1,isrc2,idest */
+{ "subs", 0x9c000000, 0x60000000, "i,2,d", E_S32 }, /* subs #const,isrc2,idest */
+
+{ "shl", 0xa0000000, 0x5c000000, "1,2,d", 0 }, /* shl isrc1,isrc2,idest */
+{ "shl", 0xa4000000, 0x58000000, "i,2,d", 0 }, /* shl #const,isrc2,idest */
+{ "shr", 0xa8000000, 0x54000000, "1,2,d", 0 }, /* shr isrc1,isrc2,idest */
+{ "shr", 0xac000000, 0x50000000, "i,2,d", 0 }, /* shr #const,isrc2,idest */
+{ "shrd", 0xb0000000, 0x4c000000, "1,2,d", 0 }, /* shrd isrc1,isrc2,idest */
+{ "shra", 0xb8000000, 0x44000000, "1,2,d", 0 }, /* shra isrc1,isrc2,idest */
+{ "shra", 0xbc000000, 0x40000000, "i,2,d", 0 }, /* shra #const,isrc2,idest */
+
+{ "mov", 0xa0000000, 0x5c00f800, "2,d", 0 }, /* shl r0,isrc2,idest */
+{ "mov", 0x94000000, 0x69e00000, "i,d", E_MOV }, /* adds #const,r0,idest */
+{ "nop", 0xa0000000, 0x5ffff800, "", 0 }, /* shl r0,r0,r0 */
+{ "fnop", 0xb0000000, 0x4ffff800, "", 0 }, /* shrd r0,r0,r0 */
+
+{ "trap", 0x44000000, 0xb8000000, "1,2,d", 0 }, /* trap isrc1ni,isrc2,idest */
+
+{ "flush", 0x34000000, 0xc81f0001, "i(2)", E_ADDR }, /* flush #const(isrc2) */
+{ "flush", 0x34000001, 0xc81f0000, "i(2)++", E_ADDR }, /* flush #const(isrc2)++ */
+
+{ "and", 0xc0000000, 0x3c000000, "1,2,d", 0 }, /* and isrc1,isrc2,idest */
+{ "and", 0xc4000000, 0x38000000, "i,2,d", E_AND }, /* and #const,isrc2,idest */
+{ "andh", 0xc8000000, 0x34000000, "1,2,d", 0 }, /* andh isrc1,isrc2,idest */
+{ "andh", 0xcc000000, 0x30000000, "i,2,d", 0 }, /* andh #const,isrc2,idest */
+{ "andnot", 0xd0000000, 0x2c000000, "1,2,d", 0 }, /* andnot isrc1,isrc2,idest */
+{ "andnot", 0xd4000000, 0x28000000, "i,2,d", E_U32 }, /* andnot #const,isrc2,idest */
+{ "andnoth", 0xd8000000, 0x24000000, "1,2,d", 0 }, /* andnoth isrc1,isrc2,idest */
+{ "andnoth", 0xdc000000, 0x20000000, "i,2,d", 0 }, /* andnoth #const,isrc2,idest */
+{ "or", 0xe0000000, 0x1c000000, "1,2,d", 0 }, /* or isrc1,isrc2,idest */
+{ "or", 0xe4000000, 0x18000000, "i,2,d", E_U32 }, /* or #const,isrc2,idest */
+{ "orh", 0xe8000000, 0x14000000, "1,2,d", 0 }, /* orh isrc1,isrc2,idest */
+{ "orh", 0xec000000, 0x10000000, "i,2,d", 0 }, /* orh #const,isrc2,idest */
+{ "xor", 0xf0000000, 0x0c000000, "1,2,d", 0 }, /* xor isrc1,isrc2,idest */
+{ "xor", 0xf4000000, 0x08000000, "i,2,d", E_U32 }, /* xor #const,isrc2,idest */
+{ "xorh", 0xf8000000, 0x04000000, "1,2,d", 0 }, /* xorh isrc1,isrc2,idest */
+{ "xorh", 0xfc000000, 0x00000000, "i,2,d", 0 }, /* xorh #const,isrc2,idest */
+
+{ "bte", 0x58000000, 0xa4000000, "1,2,s", 0 }, /* bte isrc1s,isrc2,sbroff */
+{ "bte", 0x5c000000, 0xa0000000, "5,2,s", 0 }, /* bte #const5,isrc2,sbroff */
+{ "btne", 0x50000000, 0xac000000, "1,2,s", 0 }, /* btne isrc1s,isrc2,sbroff */
+{ "btne", 0x54000000, 0xa8000000, "5,2,s", 0 }, /* btne #const5,isrc2,sbroff */
+{ "bla", 0xb4000000, 0x48000000, "1,2,s", E_DELAY }, /* bla isrc1s,isrc2,sbroff */
+{ "bri", 0x40000000, 0xbc000000, "1", E_DELAY }, /* bri isrc1ni */
+
+/* Core Escape Instruction Format */
+{ "lock", 0x4c000001, 0xb000001e, "", 0 }, /* lock set BL in dirbase */
+{ "calli", 0x4c000002, 0xb000001d, "1", E_DELAY }, /* calli isrc1ni */
+{ "intovr", 0x4c000004, 0xb000001b, "", 0 }, /* intovr trap on integer overflow */
+{ "unlock", 0x4c000007, 0xb0000018, "", 0 }, /* unlock clear BL in dirbase */
+
+/* CTRL-Format Instructions */
+{ "br", 0x68000000, 0x94000000, "l", E_DELAY }, /* br lbroff */
+{ "call", 0x6c000000, 0x90000000, "l", E_DELAY }, /* call lbroff */
+{ "bc", 0x70000000, 0x8c000000, "l", 0 }, /* bc lbroff */
+{ "bc.t", 0x74000000, 0x88000000, "l", E_DELAY }, /* bc.t lbroff */
+{ "bnc", 0x78000000, 0x84000000, "l", 0 }, /* bnc lbroff */
+{ "bnc.t", 0x7c000000, 0x80000000, "l", E_DELAY }, /* bnc.t lbroff */
+
+/* Floating Point Escape Instruction Format - pfam.p fsrc1,fsrc2,fdest */
+{ "r2p1.ss", 0x48000400, 0xb40003ff, "e,f,g", 0 },
+{ "r2p1.sd", 0x48000480, 0xb400037f, "e,f,g", 0 },
+{ "r2p1.dd", 0x48000580, 0xb400027f, "e,f,g", 0 },
+{ "r2pt.ss", 0x48000401, 0xb40003fe, "e,f,g", 0 },
+{ "r2pt.sd", 0x48000481, 0xb400037e, "e,f,g", 0 },
+{ "r2pt.dd", 0x48000581, 0xb400027e, "e,f,g", 0 },
+{ "r2ap1.ss", 0x48000402, 0xb40003fd, "e,f,g", 0 },
+{ "r2ap1.sd", 0x48000482, 0xb400037d, "e,f,g", 0 },
+{ "r2ap1.dd", 0x48000582, 0xb400027d, "e,f,g", 0 },
+{ "r2apt.ss", 0x48000403, 0xb40003fc, "e,f,g", 0 },
+{ "r2apt.sd", 0x48000483, 0xb400037c, "e,f,g", 0 },
+{ "r2apt.dd", 0x48000583, 0xb400027c, "e,f,g", 0 },
+{ "i2p1.ss", 0x48000404, 0xb40003fb, "e,f,g", 0 },
+{ "i2p1.sd", 0x48000484, 0xb400037b, "e,f,g", 0 },
+{ "i2p1.dd", 0x48000584, 0xb400027b, "e,f,g", 0 },
+{ "i2pt.ss", 0x48000405, 0xb40003fa, "e,f,g", 0 },
+{ "i2pt.sd", 0x48000485, 0xb400037a, "e,f,g", 0 },
+{ "i2pt.dd", 0x48000585, 0xb400027a, "e,f,g", 0 },
+{ "i2ap1.ss", 0x48000406, 0xb40003f9, "e,f,g", 0 },
+{ "i2ap1.sd", 0x48000486, 0xb4000379, "e,f,g", 0 },
+{ "i2ap1.dd", 0x48000586, 0xb4000279, "e,f,g", 0 },
+{ "i2apt.ss", 0x48000407, 0xb40003f8, "e,f,g", 0 },
+{ "i2apt.sd", 0x48000487, 0xb4000378, "e,f,g", 0 },
+{ "i2apt.dd", 0x48000587, 0xb4000278, "e,f,g", 0 },
+{ "rat1p2.ss", 0x48000408, 0xb40003f7, "e,f,g", 0 },
+{ "rat1p2.sd", 0x48000488, 0xb4000377, "e,f,g", 0 },
+{ "rat1p2.dd", 0x48000588, 0xb4000277, "e,f,g", 0 },
+{ "m12apm.ss", 0x48000409, 0xb40003f6, "e,f,g", 0 },
+{ "m12apm.sd", 0x48000489, 0xb4000376, "e,f,g", 0 },
+{ "m12apm.dd", 0x48000589, 0xb4000276, "e,f,g", 0 },
+{ "ra1p2.ss", 0x4800040a, 0xb40003f5, "e,f,g", 0 },
+{ "ra1p2.sd", 0x4800048a, 0xb4000375, "e,f,g", 0 },
+{ "ra1p2.dd", 0x4800058a, 0xb4000275, "e,f,g", 0 },
+{ "m12ttpa.ss", 0x4800040b, 0xb40003f4, "e,f,g", 0 },
+{ "m12ttpa.sd", 0x4800048b, 0xb4000374, "e,f,g", 0 },
+{ "m12ttpa.dd", 0x4800058b, 0xb4000274, "e,f,g", 0 },
+{ "iat1p2.ss", 0x4800040c, 0xb40003f3, "e,f,g", 0 },
+{ "iat1p2.sd", 0x4800048c, 0xb4000373, "e,f,g", 0 },
+{ "iat1p2.dd", 0x4800058c, 0xb4000273, "e,f,g", 0 },
+{ "m12tpm.ss", 0x4800040d, 0xb40003f2, "e,f,g", 0 },
+{ "m12tpm.sd", 0x4800048d, 0xb4000372, "e,f,g", 0 },
+{ "m12tpm.dd", 0x4800058d, 0xb4000272, "e,f,g", 0 },
+{ "ia1p2.ss", 0x4800040e, 0xb40003f1, "e,f,g", 0 },
+{ "ia1p2.sd", 0x4800048e, 0xb4000371, "e,f,g", 0 },
+{ "ia1p2.dd", 0x4800058e, 0xb4000271, "e,f,g", 0 },
+{ "m12tpa.ss", 0x4800040f, 0xb40003f0, "e,f,g", 0 },
+{ "m12tpa.sd", 0x4800048f, 0xb4000370, "e,f,g", 0 },
+{ "m12tpa.dd", 0x4800058f, 0xb4000270, "e,f,g", 0 },
+
+/* Floating Point Escape Instruction Format - pfsm.p fsrc1,fsrc2,fdest */
+{ "r2s1.ss", 0x48000410, 0xb40003ef, "e,f,g", 0 },
+{ "r2s1.sd", 0x48000490, 0xb400036f, "e,f,g", 0 },
+{ "r2s1.dd", 0x48000590, 0xb400026f, "e,f,g", 0 },
+{ "r2st.ss", 0x48000411, 0xb40003ee, "e,f,g", 0 },
+{ "r2st.sd", 0x48000491, 0xb400036e, "e,f,g", 0 },
+{ "r2st.dd", 0x48000591, 0xb400026e, "e,f,g", 0 },
+{ "r2as1.ss", 0x48000412, 0xb40003ed, "e,f,g", 0 },
+{ "r2as1.sd", 0x48000492, 0xb400036d, "e,f,g", 0 },
+{ "r2as1.dd", 0x48000592, 0xb400026d, "e,f,g", 0 },
+{ "r2ast.ss", 0x48000413, 0xb40003ec, "e,f,g", 0 },
+{ "r2ast.sd", 0x48000493, 0xb400036c, "e,f,g", 0 },
+{ "r2ast.dd", 0x48000593, 0xb400026c, "e,f,g", 0 },
+{ "i2s1.ss", 0x48000414, 0xb40003eb, "e,f,g", 0 },
+{ "i2s1.sd", 0x48000494, 0xb400036b, "e,f,g", 0 },
+{ "i2s1.dd", 0x48000594, 0xb400026b, "e,f,g", 0 },
+{ "i2st.ss", 0x48000415, 0xb40003ea, "e,f,g", 0 },
+{ "i2st.sd", 0x48000495, 0xb400036a, "e,f,g", 0 },
+{ "i2st.dd", 0x48000595, 0xb400026a, "e,f,g", 0 },
+{ "i2as1.ss", 0x48000416, 0xb40003e9, "e,f,g", 0 },
+{ "i2as1.sd", 0x48000496, 0xb4000369, "e,f,g", 0 },
+{ "i2as1.dd", 0x48000596, 0xb4000269, "e,f,g", 0 },
+{ "i2ast.ss", 0x48000417, 0xb40003e8, "e,f,g", 0 },
+{ "i2ast.sd", 0x48000497, 0xb4000368, "e,f,g", 0 },
+{ "i2ast.dd", 0x48000597, 0xb4000268, "e,f,g", 0 },
+{ "rat1s2.ss", 0x48000418, 0xb40003e7, "e,f,g", 0 },
+{ "rat1s2.sd", 0x48000498, 0xb4000367, "e,f,g", 0 },
+{ "rat1s2.dd", 0x48000598, 0xb4000267, "e,f,g", 0 },
+{ "m12asm.ss", 0x48000419, 0xb40003e6, "e,f,g", 0 },
+{ "m12asm.sd", 0x48000499, 0xb4000366, "e,f,g", 0 },
+{ "m12asm.dd", 0x48000599, 0xb4000266, "e,f,g", 0 },
+{ "ra1s2.ss", 0x4800041a, 0xb40003e5, "e,f,g", 0 },
+{ "ra1s2.sd", 0x4800049a, 0xb4000365, "e,f,g", 0 },
+{ "ra1s2.dd", 0x4800059a, 0xb4000265, "e,f,g", 0 },
+{ "m12ttsa.ss", 0x4800041b, 0xb40003e4, "e,f,g", 0 },
+{ "m12ttsa.sd", 0x4800049b, 0xb4000364, "e,f,g", 0 },
+{ "m12ttsa.dd", 0x4800059b, 0xb4000264, "e,f,g", 0 },
+{ "iat1s2.ss", 0x4800041c, 0xb40003e3, "e,f,g", 0 },
+{ "iat1s2.sd", 0x4800049c, 0xb4000363, "e,f,g", 0 },
+{ "iat1s2.dd", 0x4800059c, 0xb4000263, "e,f,g", 0 },
+{ "m12tsm.ss", 0x4800041d, 0xb40003e2, "e,f,g", 0 },
+{ "m12tsm.sd", 0x4800049d, 0xb4000362, "e,f,g", 0 },
+{ "m12tsm.dd", 0x4800059d, 0xb4000262, "e,f,g", 0 },
+{ "ia1s2.ss", 0x4800041e, 0xb40003e1, "e,f,g", 0 },
+{ "ia1s2.sd", 0x4800049e, 0xb4000361, "e,f,g", 0 },
+{ "ia1s2.dd", 0x4800059e, 0xb4000261, "e,f,g", 0 },
+{ "m12tsa.ss", 0x4800041f, 0xb40003e0, "e,f,g", 0 },
+{ "m12tsa.sd", 0x4800049f, 0xb4000360, "e,f,g", 0 },
+{ "m12tsa.dd", 0x4800059f, 0xb4000260, "e,f,g", 0 },
+
+/* Floating Point Escape Instruction Format - pfmam.p fsrc1,fsrc2,fdest */
+{ "mr2p1.ss", 0x48000000, 0xb40007ff, "e,f,g", 0 },
+{ "mr2p1.sd", 0x48000080, 0xb400077f, "e,f,g", 0 },
+{ "mr2p1.dd", 0x48000180, 0xb400067f, "e,f,g", 0 },
+{ "mr2pt.ss", 0x48000001, 0xb40007fe, "e,f,g", 0 },
+{ "mr2pt.sd", 0x48000081, 0xb400077e, "e,f,g", 0 },
+{ "mr2pt.dd", 0x48000181, 0xb400067e, "e,f,g", 0 },
+{ "mr2mp1.ss", 0x48000002, 0xb40007fd, "e,f,g", 0 },
+{ "mr2mp1.sd", 0x48000082, 0xb400077d, "e,f,g", 0 },
+{ "mr2mp1.dd", 0x48000182, 0xb400067d, "e,f,g", 0 },
+{ "mr2mpt.ss", 0x48000003, 0xb40007fc, "e,f,g", 0 },
+{ "mr2mpt.sd", 0x48000083, 0xb400077c, "e,f,g", 0 },
+{ "mr2mpt.dd", 0x48000183, 0xb400067c, "e,f,g", 0 },
+{ "mi2p1.ss", 0x48000004, 0xb40007fb, "e,f,g", 0 },
+{ "mi2p1.sd", 0x48000084, 0xb400077b, "e,f,g", 0 },
+{ "mi2p1.dd", 0x48000184, 0xb400067b, "e,f,g", 0 },
+{ "mi2pt.ss", 0x48000005, 0xb40007fa, "e,f,g", 0 },
+{ "mi2pt.sd", 0x48000085, 0xb400077a, "e,f,g", 0 },
+{ "mi2pt.dd", 0x48000185, 0xb400067a, "e,f,g", 0 },
+{ "mi2mp1.ss", 0x48000006, 0xb40007f9, "e,f,g", 0 },
+{ "mi2mp1.sd", 0x48000086, 0xb4000779, "e,f,g", 0 },
+{ "mi2mp1.dd", 0x48000186, 0xb4000679, "e,f,g", 0 },
+{ "mi2mpt.ss", 0x48000007, 0xb40007f8, "e,f,g", 0 },
+{ "mi2mpt.sd", 0x48000087, 0xb4000778, "e,f,g", 0 },
+{ "mi2mpt.dd", 0x48000187, 0xb4000678, "e,f,g", 0 },
+{ "mrmt1p2.ss", 0x48000008, 0xb40007f7, "e,f,g", 0 },
+{ "mrmt1p2.sd", 0x48000088, 0xb4000777, "e,f,g", 0 },
+{ "mrmt1p2.dd", 0x48000188, 0xb4000677, "e,f,g", 0 },
+{ "mm12mpm.ss", 0x48000009, 0xb40007f6, "e,f,g", 0 },
+{ "mm12mpm.sd", 0x48000089, 0xb4000776, "e,f,g", 0 },
+{ "mm12mpm.dd", 0x48000189, 0xb4000676, "e,f,g", 0 },
+{ "mrm1p2.ss", 0x4800000a, 0xb40007f5, "e,f,g", 0 },
+{ "mrm1p2.sd", 0x4800008a, 0xb4000775, "e,f,g", 0 },
+{ "mrm1p2.dd", 0x4800018a, 0xb4000675, "e,f,g", 0 },
+{ "mm12ttpm.ss",0x4800000b, 0xb40007f4, "e,f,g", 0 },
+{ "mm12ttpm.sd",0x4800008b, 0xb4000774, "e,f,g", 0 },
+{ "mm12ttpm.dd",0x4800018b, 0xb4000674, "e,f,g", 0 },
+{ "mimt1p2.ss", 0x4800000c, 0xb40007f3, "e,f,g", 0 },
+{ "mimt1p2.sd", 0x4800008c, 0xb4000773, "e,f,g", 0 },
+{ "mimt1p2.dd", 0x4800018c, 0xb4000673, "e,f,g", 0 },
+{ "mm12tpm.ss", 0x4800000d, 0xb40007f2, "e,f,g", 0 },
+{ "mm12tpm.sd", 0x4800008d, 0xb4000772, "e,f,g", 0 },
+{ "mm12tpm.dd", 0x4800018d, 0xb4000672, "e,f,g", 0 },
+{ "mim1p2.ss", 0x4800000e, 0xb40007f1, "e,f,g", 0 },
+{ "mim1p2.sd", 0x4800008e, 0xb4000771, "e,f,g", 0 },
+{ "mim1p2.dd", 0x4800018e, 0xb4000671, "e,f,g", 0 },
+
+/* Floating Point Escape Instruction Format - pfmsm.p fsrc1,fsrc2,fdest */
+{ "mr2s1.ss", 0x48000010, 0xb40007ef, "e,f,g", 0 },
+{ "mr2s1.sd", 0x48000090, 0xb400076f, "e,f,g", 0 },
+{ "mr2s1.dd", 0x48000190, 0xb400066f, "e,f,g", 0 },
+{ "mr2st.ss", 0x48000011, 0xb40007ee, "e,f,g", 0 },
+{ "mr2st.sd", 0x48000091, 0xb400076e, "e,f,g", 0 },
+{ "mr2st.dd", 0x48000191, 0xb400066e, "e,f,g", 0 },
+{ "mr2ms1.ss", 0x48000012, 0xb40007ed, "e,f,g", 0 },
+{ "mr2ms1.sd", 0x48000092, 0xb400076d, "e,f,g", 0 },
+{ "mr2ms1.dd", 0x48000192, 0xb400066d, "e,f,g", 0 },
+{ "mr2mst.ss", 0x48000013, 0xb40007ec, "e,f,g", 0 },
+{ "mr2mst.sd", 0x48000093, 0xb400076c, "e,f,g", 0 },
+{ "mr2mst.dd", 0x48000193, 0xb400066c, "e,f,g", 0 },
+{ "mi2s1.ss", 0x48000014, 0xb40007eb, "e,f,g", 0 },
+{ "mi2s1.sd", 0x48000094, 0xb400076b, "e,f,g", 0 },
+{ "mi2s1.dd", 0x48000194, 0xb400066b, "e,f,g", 0 },
+{ "mi2st.ss", 0x48000015, 0xb40007ea, "e,f,g", 0 },
+{ "mi2st.sd", 0x48000095, 0xb400076a, "e,f,g", 0 },
+{ "mi2st.dd", 0x48000195, 0xb400066a, "e,f,g", 0 },
+{ "mi2ms1.ss", 0x48000016, 0xb40007e9, "e,f,g", 0 },
+{ "mi2ms1.sd", 0x48000096, 0xb4000769, "e,f,g", 0 },
+{ "mi2ms1.dd", 0x48000196, 0xb4000669, "e,f,g", 0 },
+{ "mi2mst.ss", 0x48000017, 0xb40007e8, "e,f,g", 0 },
+{ "mi2mst.sd", 0x48000097, 0xb4000768, "e,f,g", 0 },
+{ "mi2mst.dd", 0x48000197, 0xb4000668, "e,f,g", 0 },
+{ "mrmt1s2.ss", 0x48000018, 0xb40007e7, "e,f,g", 0 },
+{ "mrmt1s2.sd", 0x48000098, 0xb4000767, "e,f,g", 0 },
+{ "mrmt1s2.dd", 0x48000198, 0xb4000667, "e,f,g", 0 },
+{ "mm12msm.ss", 0x48000019, 0xb40007e6, "e,f,g", 0 },
+{ "mm12msm.sd", 0x48000099, 0xb4000766, "e,f,g", 0 },
+{ "mm12msm.dd", 0x48000199, 0xb4000666, "e,f,g", 0 },
+{ "mrm1s2.ss", 0x4800001a, 0xb40007e5, "e,f,g", 0 },
+{ "mrm1s2.sd", 0x4800009a, 0xb4000765, "e,f,g", 0 },
+{ "mrm1s2.dd", 0x4800019a, 0xb4000665, "e,f,g", 0 },
+{ "mm12ttsm.ss",0x4800001b, 0xb40007e4, "e,f,g", 0 },
+{ "mm12ttsm.sd",0x4800009b, 0xb4000764, "e,f,g", 0 },
+{ "mm12ttsm.dd",0x4800019b, 0xb4000664, "e,f,g", 0 },
+{ "mimt1s2.ss", 0x4800001c, 0xb40007e3, "e,f,g", 0 },
+{ "mimt1s2.sd", 0x4800009c, 0xb4000763, "e,f,g", 0 },
+{ "mimt1s2.dd", 0x4800019c, 0xb4000663, "e,f,g", 0 },
+{ "mm12tsm.ss", 0x4800001d, 0xb40007e2, "e,f,g", 0 },
+{ "mm12tsm.sd", 0x4800009d, 0xb4000762, "e,f,g", 0 },
+{ "mm12tsm.dd", 0x4800019d, 0xb4000662, "e,f,g", 0 },
+{ "mim1s2.ss", 0x4800001e, 0xb40007e1, "e,f,g", 0 },
+{ "mim1s2.sd", 0x4800009e, 0xb4000761, "e,f,g", 0 },
+{ "mim1s2.dd", 0x4800019e, 0xb4000661, "e,f,g", 0 },
+
+
+{ "fmul.ss", 0x48000020, 0xb40007df, "e,f,g", 0 }, /* fmul.p fsrc1,fsrc2,fdest */
+{ "fmul.sd", 0x480000a0, 0xb400075f, "e,f,g", 0 }, /* fmul.p fsrc1,fsrc2,fdest */
+{ "fmul.dd", 0x480001a0, 0xb400065f, "e,f,g", 0 }, /* fmul.p fsrc1,fsrc2,fdest */
+{ "pfmul.ss", 0x48000420, 0xb40003df, "e,f,g", 0 }, /* pfmul.p fsrc1,fsrc2,fdest */
+{ "pfmul.sd", 0x480004a0, 0xb400035f, "e,f,g", 0 }, /* pfmul.p fsrc1,fsrc2,fdest */
+{ "pfmul.dd", 0x480005a0, 0xb400025f, "e,f,g", 0 }, /* pfmul.p fsrc1,fsrc2,fdest */
+{ "pfmul3.dd", 0x480005a4, 0xb400025b, "e,f,g", 0 }, /* pfmul3.p fsrc1,fsrc2,fdest */
+{ "fmlow.dd", 0x480001a1, 0xb400065e, "e,f,g", 0 }, /* fmlow.dd fsrc1,fsrc2,fdest */
+{ "frcp.ss", 0x48000022, 0xb40007dd, "f,g", 0 }, /* frcp.p fsrc2,fdest */
+{ "frcp.sd", 0x480000a2, 0xb400075d, "f,g", 0 }, /* frcp.p fsrc2,fdest */
+{ "frcp.dd", 0x480001a2, 0xb400065d, "f,g", 0 }, /* frcp.p fsrc2,fdest */
+{ "frsqr.ss", 0x48000023, 0xb40007dc, "f,g", 0 }, /* frsqr.p fsrc2,fdest */
+{ "frsqr.sd", 0x480000a3, 0xb400075c, "f,g", 0 }, /* frsqr.p fsrc2,fdest */
+{ "frsqr.dd", 0x480001a3, 0xb400065c, "f,g", 0 }, /* frsqr.p fsrc2,fdest */
+{ "fadd.ss", 0x48000030, 0xb40007cf, "e,f,g", 0 }, /* fadd.p fsrc1,fsrc2,fdest */
+{ "fadd.sd", 0x480000b0, 0xb400074f, "e,f,g", 0 }, /* fadd.p fsrc1,fsrc2,fdest */
+{ "fadd.dd", 0x480001b0, 0xb400064f, "e,f,g", 0 }, /* fadd.p fsrc1,fsrc2,fdest */
+{ "pfadd.ss", 0x48000430, 0xb40003cf, "e,f,g", 0 }, /* pfadd.p fsrc1,fsrc2,fdest */
+{ "pfadd.sd", 0x480004b0, 0xb400034f, "e,f,g", 0 }, /* pfadd.p fsrc1,fsrc2,fdest */
+{ "pfadd.dd", 0x480005b0, 0xb400024f, "e,f,g", 0 }, /* pfadd.p fsrc1,fsrc2,fdest */
+{ "fsub.ss", 0x48000031, 0xb40007ce, "e,f,g", 0 }, /* fsub.p fsrc1,fsrc2,fdest */
+{ "fsub.sd", 0x480000b1, 0xb400074e, "e,f,g", 0 }, /* fsub.p fsrc1,fsrc2,fdest */
+{ "fsub.dd", 0x480001b1, 0xb400064e, "e,f,g", 0 }, /* fsub.p fsrc1,fsrc2,fdest */
+{ "pfsub.ss", 0x48000431, 0xb40003ce, "e,f,g", 0 }, /* pfsub.p fsrc1,fsrc2,fdest */
+{ "pfsub.sd", 0x480004b1, 0xb400034e, "e,f,g", 0 }, /* pfsub.p fsrc1,fsrc2,fdest */
+{ "pfsub.dd", 0x480005b1, 0xb400024e, "e,f,g", 0 }, /* pfsub.p fsrc1,fsrc2,fdest */
+{ "fix.ss", 0x48000032, 0xb40007cd, "e,g", 0 }, /* fix.p fsrc1,fdest */
+{ "fix.sd", 0x480000b2, 0xb400074d, "e,g", 0 }, /* fix.p fsrc1,fdest */
+{ "fix.dd", 0x480001b2, 0xb400064d, "e,g", 0 }, /* fix.p fsrc1,fdest */
+{ "pfix.ss", 0x48000432, 0xb40003cd, "e,g", 0 }, /* pfix.p fsrc1,fdest */
+{ "pfix.sd", 0x480004b2, 0xb400034d, "e,g", 0 }, /* pfix.p fsrc1,fdest */
+{ "pfix.dd", 0x480005b2, 0xb400024d, "e,g", 0 }, /* pfix.p fsrc1,fdest */
+{ "famov.ss", 0x48000033, 0xb40007cc, "e,g", 0 }, /* famov.p fsrc1,fdest */
+{ "famov.ds", 0x48000133, 0xb40006cc, "e,g", 0 }, /* famov.p fsrc1,fdest */
+{ "famov.sd", 0x480000b3, 0xb400074c, "e,g", 0 }, /* famov.p fsrc1,fdest */
+{ "famov.dd", 0x480001b3, 0xb400064c, "e,g", 0 }, /* famov.p fsrc1,fdest */
+{ "pfamov.ss", 0x48000433, 0xb40003cc, "e,g", 0 }, /* pfamov.p fsrc1,fdest */
+{ "pfamov.ds", 0x48000533, 0xb40002cc, "e,g", 0 }, /* pfamov.p fsrc1,fdest */
+{ "pfamov.sd", 0x480004b3, 0xb400034c, "e,g", 0 }, /* pfamov.p fsrc1,fdest */
+{ "pfamov.dd", 0x480005b3, 0xb400024c, "e,g", 0 }, /* pfamov.p fsrc1,fdest */
+/* pfgt has R bit cleared; pfle has R bit set */
+{ "pfgt.ss", 0x48000434, 0xb40003cb, "e,f,g", 0 }, /* pfgt.p fsrc1,fsrc2,fdest */
+{ "pfgt.sd", 0x48000434, 0xb40003cb, "e,f,g", 0 }, /* pfgt.p fsrc1,fsrc2,fdest */
+{ "pfgt.dd", 0x48000534, 0xb40002cb, "e,f,g", 0 }, /* pfgt.p fsrc1,fsrc2,fdest */
+/* pfgt has R bit cleared; pfle has R bit set */
+{ "pfle.ss", 0x480004b4, 0xb400034b, "e,f,g", 0 }, /* pfle.p fsrc1,fsrc2,fdest */
+{ "pfle.sd", 0x480004b4, 0xb400034b, "e,f,g", 0 }, /* pfle.p fsrc1,fsrc2,fdest */
+{ "pfle.dd", 0x480005b4, 0xb400024b, "e,f,g", 0 }, /* pfle.p fsrc1,fsrc2,fdest */
+{ "ftrunc.ss", 0x4800003a, 0xb40007c5, "e,g", 0 }, /* ftrunc.p fsrc1,fdest */
+{ "ftrunc.sd", 0x480000ba, 0xb4000745, "e,g", 0 }, /* ftrunc.p fsrc1,fdest */
+{ "ftrunc.dd", 0x480001ba, 0xb4000645, "e,g", 0 }, /* ftrunc.p fsrc1,fdest */
+{ "pftrunc.ss", 0x4800043a, 0xb40003c5, "e,g", 0 }, /* pftrunc.p fsrc1,fdest */
+{ "pftrunc.sd", 0x480004ba, 0xb4000345, "e,g", 0 }, /* pftrunc.p fsrc1,fdest */
+{ "pftrunc.dd", 0x480005ba, 0xb4000245, "e,g", 0 }, /* pftrunc.p fsrc1,fdest */
+{ "fxfr", 0x48000040, 0xb40007bf, "e,d", 0 }, /* fxfr fsrc1,idest */
+{ "fiadd.ss", 0x48000049, 0xb40007b6, "e,f,g", 0 }, /* fiadd.w fsrc1,fsrc2,fdest */
+{ "fiadd.dd", 0x480001c9, 0xb4000636, "e,f,g", 0 }, /* fiadd.w fsrc1,fsrc2,fdest */
+{ "pfiadd.ss", 0x48000449, 0xb40003b6, "e,f,g", 0 }, /* pfiadd.w fsrc1,fsrc2,fdest */
+{ "pfiadd.dd", 0x480005c9, 0xb4000236, "e,f,g", 0 }, /* pfiadd.w fsrc1,fsrc2,fdest */
+{ "fisub.ss", 0x4800004d, 0xb40007b2, "e,f,g", 0 }, /* fisub.w fsrc1,fsrc2,fdest */
+{ "fisub.dd", 0x480001cd, 0xb4000632, "e,f,g", 0 }, /* fisub.w fsrc1,fsrc2,fdest */
+{ "pfisub.ss", 0x4800044d, 0xb40003b2, "e,f,g", 0 }, /* pfisub.w fsrc1,fsrc2,fdest */
+{ "pfisub.dd", 0x480005cd, 0xb4000232, "e,f,g", 0 }, /* pfisub.w fsrc1,fsrc2,fdest */
+{ "fzchkl", 0x48000057, 0xb40007a8, "e,f,g", 0 }, /* fzchkl fsrc1,fsrc2,fdest */
+{ "pfzchkl", 0x48000457, 0xb40003a8, "e,f,g", 0 }, /* pfzchkl fsrc1,fsrc2,fdest */
+{ "fzchks", 0x4800005f, 0xb40007a0, "e,f,g", 0 }, /* fzchks fsrc1,fsrc2,fdest */
+{ "pfzchks", 0x4800045f, 0xb40003a0, "e,f,g", 0 }, /* pfzchks fsrc1,fsrc2,fdest */
+{ "faddp", 0x48000050, 0xb40007af, "e,f,g", 0 }, /* faddp fsrc1,fsrc2,fdest */
+{ "pfaddp", 0x48000450, 0xb40003af, "e,f,g", 0 }, /* pfaddp fsrc1,fsrc2,fdest */
+{ "faddz", 0x48000051, 0xb40007ae, "e,f,g", 0 }, /* faddz fsrc1,fsrc2,fdest */
+{ "pfaddz", 0x48000451, 0xb40003ae, "e,f,g", 0 }, /* pfaddz fsrc1,fsrc2,fdest */
+{ "form", 0x4800005a, 0xb40007a5, "e,g", 0 }, /* form fsrc1,fdest */
+{ "pform", 0x4800045a, 0xb40003a5, "e,g", 0 }, /* pform fsrc1,fdest */
+
+/* Floating point pseudo-instructions */
+{ "fmov.ss", 0x48000049, 0xb7e007b6, "e,g", 0 }, /* fiadd.ss fsrc1,f0,fdest */
+{ "fmov.dd", 0x480001c9, 0xb7e00636, "e,g", 0 }, /* fiadd.dd fsrc1,f0,fdest */
+{ "fmov.sd", 0x480000b0, 0xb7e0074f, "e,g", 0 }, /* fadd.sd fsrc1,f0,fdest */
+{ "fmov.ds", 0x48000130, 0xb7e006cf, "e,g", 0 }, /* fadd.ds fsrc1,f0,fdest */
+{ "pfmov.ds", 0x48000530, 0xb73002cf, "e,g", 0 }, /* pfadd.ds fsrc1,f0,fdest */
+{ "pfmov.dd", 0x480005c9, 0xb7e00236, "e,g", 0 }, /* pfiadd.dd fsrc1,f0,fdest */
+
+
+};
+
+#define NUMOPCODES ((sizeof i860_opcodes)/(sizeof i860_opcodes[0]))
+
+
diff --git a/gnu/usr.bin/gas/config/i860.c b/gnu/usr.bin/gas/config/i860.c
new file mode 100644
index 00000000000..96669435698
--- /dev/null
+++ b/gnu/usr.bin/gas/config/i860.c
@@ -0,0 +1,1142 @@
+/* i860.c -- Assemble for the I860
+ Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+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>
+#include <ctype.h>
+
+#include "i860-opcode.h"
+#include "as.h"
+#include "frags.h"
+#include "struc-symbol.h"
+#include "flonum.h"
+#include "expr.h"
+#include "hash.h"
+#include "md.h"
+#include "i860.h" /* position dependent redefine */
+#include "write.h"
+#include "read.h"
+#include "symbols.h"
+
+void md_begin();
+void md_end();
+void md_number_to_chars();
+void md_assemble();
+char *md_atof();
+void md_convert_frag();
+void md_create_short_jump();
+void md_create_long_jump();
+int md_estimate_size_before_relax();
+void md_number_to_imm();
+void md_number_to_disp();
+void md_number_to_field();
+void md_ri_to_chars();
+static void i860_ip();
+void emit_relocations();
+
+const relax_typeS md_relax_table[] = { 0 };
+
+/* handle of the OPCODE hash table */
+static struct hash_control *op_hash = NULL;
+
+static void s_dual(), s_enddual();
+static void s_atmp();
+
+const pseudo_typeS
+md_pseudo_table[] = {
+ { "dual", s_dual, 4 },
+ { "enddual", s_enddual, 4 },
+ { "atmp", s_atmp, 4 },
+ { NULL, 0, 0 },
+};
+
+int md_short_jump_size = 4;
+int md_long_jump_size = 4;
+int omagic = OMAGIC; /* Magic number for header */
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful */
+char comment_chars[] = "!/"; /* JF removed '|' from comment_chars */
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that '/*' will always start a comment */
+char line_comment_chars[] = "#/";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+/* 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.
+ */
+int size_reloc_info = sizeof(struct relocation_info);
+
+static unsigned char octal[256];
+#define isoctal(c) octal[c]
+static unsigned char toHex[256];
+
+struct i860_it {
+ char *error;
+ unsigned long opcode;
+ struct nlist *nlistp;
+ expressionS exp;
+ int pcrel;
+ enum expand_type expand;
+ enum highlow_type highlow;
+ enum reloc_type reloc;
+} the_insn;
+
+#ifdef __STDC__
+static void print_insn(struct i860_it *insn);
+static int getExpression(char *str);
+#else
+static void print_insn();
+static int getExpression();
+#endif
+static char *expr_end;
+static char last_expand; /* error if expansion after branch */
+
+enum dual
+{
+ DUAL_OFF = 0, DUAL_ON, DUAL_DDOT, DUAL_ONDDOT,
+};
+static enum dual dual_mode = DUAL_OFF; /* dual-instruction mode */
+
+static void
+s_dual() /* floating point instructions have dual set */
+{
+ dual_mode = DUAL_ON;
+}
+
+static void
+s_enddual() /* floating point instructions have dual set */
+{
+ dual_mode = DUAL_OFF;
+}
+
+static int atmp = 31; /* temporary register for pseudo's */
+
+static void
+s_atmp()
+{
+ register int temp;
+ if (strncmp(input_line_pointer, "sp", 2) == 0) {
+ input_line_pointer += 2;
+ atmp = 2;
+ }
+ else if (strncmp(input_line_pointer, "fp", 2) == 0) {
+ input_line_pointer += 2;
+ atmp = 3;
+ }
+ else if (strncmp(input_line_pointer, "r", 1) == 0) {
+ input_line_pointer += 1;
+ temp = get_absolute_expression();
+ if (temp >= 0 && temp <= 31)
+ atmp = temp;
+ else
+ as_warn("Unknown temporary pseudo register");
+ }
+ else {
+ as_warn("Unknown temporary pseudo register");
+ }
+ demand_empty_rest_of_line();
+ return;
+}
+
+/* This function is called once, at assembler startup time. It should
+ set up all the tables, etc. that the MD part of the assembler will need. */
+void
+md_begin()
+{
+ register char *retval = NULL;
+ int lose = 0;
+ register unsigned int i = 0;
+
+ op_hash = hash_new();
+ if (op_hash == NULL)
+ as_fatal("Virtual memory exhausted");
+
+ while (i < NUMOPCODES)
+ {
+ const char *name = i860_opcodes[i].name;
+ retval = hash_insert(op_hash, name, &i860_opcodes[i]);
+ if(retval != NULL && *retval != '\0')
+ {
+ fprintf (stderr, "internal error: can't hash `%s': %s\n",
+ i860_opcodes[i].name, retval);
+ lose = 1;
+ }
+ do
+ {
+ if (i860_opcodes[i].match & i860_opcodes[i].lose)
+ {
+ fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
+ i860_opcodes[i].name, i860_opcodes[i].args);
+ lose = 1;
+ }
+ ++i;
+ } while (i < NUMOPCODES
+ && !strcmp(i860_opcodes[i].name, name));
+ }
+
+ if (lose)
+ as_fatal ("Broken assembler. No assembly attempted.");
+
+ for (i = '0'; i < '8'; ++i)
+ octal[i] = 1;
+ for (i = '0'; i <= '9'; ++i)
+ toHex[i] = i - '0';
+ for (i = 'a'; i <= 'f'; ++i)
+ toHex[i] = i + 10 - 'a';
+ for (i = 'A'; i <= 'F'; ++i)
+ toHex[i] = i + 10 - 'A';
+}
+
+void
+md_end()
+{
+ return;
+}
+
+void
+md_assemble(str)
+ char *str;
+{
+ char *toP;
+ int rsd;
+ int no_opcodes = 1;
+ int i;
+ struct i860_it pseudo[3];
+
+ assert(str);
+ i860_ip(str);
+
+ /* check for expandable flag to produce pseudo-instructions */
+ if (the_insn.expand != 0 && the_insn.highlow == NO_SPEC) {
+ for (i = 0; i < 3; i++)
+ pseudo[i] = the_insn;
+
+ switch (the_insn.expand) {
+
+ case E_DELAY:
+ no_opcodes = 1;
+ break;
+
+ case E_MOV:
+ if (the_insn.exp.X_add_symbol == NULL &&
+ the_insn.exp.X_subtract_symbol == NULL &&
+ (the_insn.exp.X_add_number < (1 << 15) &&
+ the_insn.exp.X_add_number >= -(1 << 15)))
+ break;
+ /* or l%const,r0,ireg_dest */
+ pseudo[0].opcode = (the_insn.opcode & 0x001f0000) | 0xe4000000;
+ pseudo[0].highlow = PAIR;
+ /* orh h%const,ireg_dest,ireg_dest */
+ pseudo[1].opcode = (the_insn.opcode & 0x03ffffff) | 0xec000000 |
+ ((the_insn.opcode & 0x001f0000) << 5);
+ pseudo[1].highlow = HIGH;
+ no_opcodes = 2;
+ break;
+
+ case E_ADDR:
+ if (the_insn.exp.X_add_symbol == NULL &&
+ the_insn.exp.X_subtract_symbol == NULL)
+ break;
+ /* orh ha%addr_expr,r0,r31 */
+ pseudo[0].opcode = 0xec000000 | (atmp<<16);
+ pseudo[0].highlow = HIGHADJ;
+ pseudo[0].reloc = LOW0; /* must overwrite */
+ /* l%addr_expr(r31),ireg_dest */
+ pseudo[1].opcode = (the_insn.opcode & ~0x003e0000) | (atmp << 21);
+ pseudo[1].highlow = PAIR;
+ no_opcodes = 2;
+ break;
+
+ case E_U32: /* 2nd version emulates Intel as, not doc. */
+ if (the_insn.exp.X_add_symbol == NULL &&
+ the_insn.exp.X_subtract_symbol == NULL &&
+ (the_insn.exp.X_add_number < (1 << 16) &&
+ the_insn.exp.X_add_number >= 0))
+ break;
+ /* $(opcode)h h%const,ireg_src2,ireg_dest
+ pseudo[0].opcode = (the_insn.opcode & 0xf3ffffff) | 0x0c000000; */
+ /* $(opcode)h h%const,ireg_src2,r31 */
+ pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000 |
+ (atmp << 16);
+ pseudo[0].highlow = HIGH;
+ /* $(opcode) l%const,ireg_dest,ireg_dest
+ pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000 |
+ ((the_insn.opcode & 0x001f0000) << 5); */
+ /* $(opcode) l%const,r31,ireg_dest */
+ pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000 |
+ (atmp << 21);
+ pseudo[1].highlow = PAIR;
+ no_opcodes = 2;
+ break;
+
+ case E_AND: /* 2nd version emulates Intel as, not doc. */
+ if (the_insn.exp.X_add_symbol == NULL &&
+ the_insn.exp.X_subtract_symbol == NULL &&
+ (the_insn.exp.X_add_number < (1 << 16) &&
+ the_insn.exp.X_add_number >= 0))
+ break;
+ /* andnot h%const,ireg_src2,ireg_dest
+ pseudo[0].opcode = (the_insn.opcode & 0x03ffffff) | 0xd4000000; */
+ /* andnot h%const,ireg_src2,r31 */
+ pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000 |
+ (atmp << 16);
+ pseudo[0].highlow = HIGH;
+ pseudo[0].exp.X_add_number = -1 - the_insn.exp.X_add_number;
+ /* andnot l%const,ireg_dest,ireg_dest
+ pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000 |
+ ((the_insn.opcode & 0x001f0000) << 5); */
+ /* andnot l%const,r31,ireg_dest */
+ pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000 |
+ (atmp << 21);
+ pseudo[1].highlow = PAIR;
+ pseudo[1].exp.X_add_number = -1 - the_insn.exp.X_add_number;
+ no_opcodes = 2;
+ break;
+
+ case E_S32:
+ if (the_insn.exp.X_add_symbol == NULL &&
+ the_insn.exp.X_subtract_symbol == NULL &&
+ (the_insn.exp.X_add_number < (1 << 15) &&
+ the_insn.exp.X_add_number >= -(1 << 15)))
+ break;
+ /* orh h%const,r0,r31 */
+ pseudo[0].opcode = 0xec000000 | (atmp << 16);
+ pseudo[0].highlow = HIGH;
+ /* or l%const,r31,r31 */
+ pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16);
+ pseudo[1].highlow = PAIR;
+ /* r31,ireg_src2,ireg_dest */
+ pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11);
+ pseudo[2].reloc = NO_RELOC;
+ no_opcodes = 3;
+ break;
+
+ default:
+ abort();
+ }
+
+ the_insn = pseudo[0];
+ /* check for expanded opcode after branch or in dual */
+ if (no_opcodes > 1 && last_expand == TRUE)
+ as_warn("Expanded opcode after delayed branch: `%s'", str);
+ if (no_opcodes > 1 && dual_mode != DUAL_OFF)
+ as_warn("Expanded opcode in dual mode: `%s'", str);
+ }
+
+ i = 0;
+ do { /* always produce at least one opcode */
+ toP = frag_more(4);
+ /* put out the opcode */
+ md_number_to_chars(toP, the_insn.opcode, 4);
+
+ /* check for expanded opcode after branch or in dual */
+ last_expand = the_insn.pcrel;
+
+ /* put out the symbol-dependent stuff */
+ if (the_insn.reloc != NO_RELOC) {
+ fix_new(
+ frag_now, /* which frag */
+ (toP - frag_now->fr_literal), /* where */
+ 4, /* size */
+ the_insn.exp.X_add_symbol,
+ the_insn.exp.X_subtract_symbol,
+ the_insn.exp.X_add_number,
+ the_insn.pcrel,
+ /* merge bit fields into one argument */
+ (int)(((the_insn.highlow & 0x3) << 4) | (the_insn.reloc & 0xf))
+ );
+ }
+ the_insn = pseudo[++i];
+ } while (--no_opcodes > 0);
+
+}
+
+static void
+i860_ip(str)
+ char *str;
+{
+ char *s;
+ const char *args;
+ char c;
+ unsigned long i;
+ struct i860_opcode *insn;
+ char *argsStart;
+ unsigned long opcode;
+ unsigned int mask;
+ int match = FALSE;
+ int comma = 0;
+
+
+ for (s = str; islower(*s) || *s == '.' || *s == '3'; ++s)
+ ;
+ switch (*s) {
+
+ case '\0':
+ break;
+
+ case ',':
+ comma = 1;
+
+ /*FALLTHROUGH*/
+
+ case ' ':
+ *s++ = '\0';
+ break;
+
+ default:
+ as_warn("Unknown opcode: `%s'", str);
+ exit(1);
+ }
+
+ if (strncmp(str, "d.", 2) == 0) { /* check for d. opcode prefix */
+ if (dual_mode == DUAL_ON)
+ dual_mode = DUAL_ONDDOT;
+ else
+ dual_mode = DUAL_DDOT;
+ str += 2;
+ }
+
+ if ((insn = (struct i860_opcode *) hash_find(op_hash, str)) == NULL) {
+ if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT)
+ str -= 2;
+ as_warn("Unknown opcode: `%s'", str);
+ return;
+ }
+ if (comma) {
+ *--s = ',';
+ }
+ argsStart = s;
+ for (;;) {
+ opcode = insn->match;
+ bzero(&the_insn, sizeof(the_insn));
+ the_insn.reloc = NO_RELOC;
+
+ /*
+ * Build the opcode, checking as we go to make
+ * sure that the operands match
+ */
+ for (args = insn->args; ; ++args) {
+ switch (*args) {
+
+ case '\0': /* end of args */
+ if (*s == '\0') {
+ match = TRUE;
+ }
+ break;
+
+ case '+':
+ case '(': /* these must match exactly */
+ case ')':
+ case ',':
+ case ' ':
+ if (*s++ == *args)
+ continue;
+ break;
+
+ case '#': /* must be at least one digit */
+ if (isdigit(*s++)) {
+ while (isdigit(*s)) {
+ ++s;
+ }
+ continue;
+ }
+ break;
+
+ case '1': /* next operand must be a register */
+ case '2':
+ case 'd':
+ switch (*s) {
+
+ case 'f': /* frame pointer */
+ s++;
+ if (*s++ == 'p') {
+ mask = 0x3;
+ break;
+ }
+ goto error;
+
+ case 's': /* stack pointer */
+ s++;
+ if (*s++ == 'p') {
+ mask= 0x2;
+ break;
+ }
+ goto error;
+
+ case 'r': /* any register */
+ s++;
+ if (!isdigit(c = *s++)) {
+ goto error;
+ }
+ if (isdigit(*s)) {
+ if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) {
+ goto error;
+ }
+ } else {
+ c -= '0';
+ }
+ mask= c;
+ break;
+
+ default: /* not this opcode */
+ goto error;
+ }
+ /*
+ * Got the register, now figure out where
+ * it goes in the opcode.
+ */
+ switch (*args) {
+
+ case '1':
+ opcode |= mask << 11;
+ continue;
+
+ case '2':
+ opcode |= mask << 21;
+ continue;
+
+ case 'd':
+ opcode |= mask << 16;
+ continue;
+
+ }
+ break;
+
+ case 'e': /* next operand is a floating point register */
+ case 'f':
+ case 'g':
+ if (*s++ == 'f' && isdigit(*s)) {
+ mask = *s++;
+ if (isdigit(*s)) {
+ mask = 10 * (mask - '0') + (*s++ - '0');
+ if (mask >= 32) {
+ break;
+ }
+ } else {
+ mask -= '0';
+ }
+ switch (*args) {
+
+ case 'e':
+ opcode |= mask << 11;
+ continue;
+
+ case 'f':
+ opcode |= mask << 21;
+ continue;
+
+ case 'g':
+ opcode |= mask << 16;
+ if (dual_mode != DUAL_OFF)
+ opcode |= (1 << 9); /* dual mode instruction */
+ if (dual_mode == DUAL_DDOT)
+ dual_mode = DUAL_OFF;
+ if (dual_mode == DUAL_ONDDOT)
+ dual_mode = DUAL_ON;
+ if ((opcode & (1 << 10)) && (mask == ((opcode >> 11) & 0x1f)))
+ as_warn("Fsr1 equals fdest with Pipelining");
+ continue;
+ }
+ }
+ break;
+
+ case 'c': /* next operand must be a control register */
+ if (strncmp(s, "fir", 3) == 0) {
+ opcode |= 0x0 << 21;
+ s += 3;
+ continue;
+ }
+ if (strncmp(s, "psr", 3) == 0) {
+ opcode |= 0x1 << 21;
+ s += 3;
+ continue;
+ }
+ if (strncmp(s, "dirbase", 7) == 0) {
+ opcode |= 0x2 << 21;
+ s += 7;
+ continue;
+ }
+ if (strncmp(s, "db", 2) == 0) {
+ opcode |= 0x3 << 21;
+ s += 2;
+ continue;
+ }
+ if (strncmp(s, "fsr", 3) == 0) {
+ opcode |= 0x4 << 21;
+ s += 3;
+ continue;
+ }
+ if (strncmp(s, "epsr", 4) == 0) {
+ opcode |= 0x5 << 21;
+ s += 4;
+ continue;
+ }
+ break;
+
+ case '5': /* 5 bit immediate in src1 */
+ bzero(&the_insn, sizeof(the_insn));
+ if ( !getExpression(s)) {
+ s = expr_end;
+ if (the_insn.exp.X_add_number & ~0x1f)
+ as_warn("5-bit immediate too large");
+ opcode |= (the_insn.exp.X_add_number & 0x1f) << 11;
+ bzero(&the_insn, sizeof(the_insn));
+ the_insn.reloc = NO_RELOC;
+ continue;
+ }
+ break;
+
+ case 'l': /* 26 bit immediate, relative branch */
+ the_insn.reloc = BRADDR;
+ the_insn.pcrel = TRUE;
+ goto immediate;
+
+ case 's': /* 16 bit immediate, split relative branch */
+ /* upper 5 bits of offset in dest field */
+ the_insn.pcrel = TRUE;
+ the_insn.reloc = SPLIT0;
+ goto immediate;
+
+ case 'S': /* 16 bit immediate, split (st), aligned */
+ if (opcode & (1 << 28))
+ if (opcode & 0x1)
+ the_insn.reloc = SPLIT2;
+ else
+ the_insn.reloc = SPLIT1;
+ else
+ the_insn.reloc = SPLIT0;
+ goto immediate;
+
+ case 'I': /* 16 bit immediate, aligned */
+ if (opcode & (1 << 28))
+ if (opcode & 0x1)
+ the_insn.reloc = LOW2;
+ else
+ the_insn.reloc = LOW1;
+ else
+ the_insn.reloc = LOW0;
+ goto immediate;
+
+ case 'i': /* 16 bit immediate */
+ the_insn.reloc = LOW0;
+
+ /*FALLTHROUGH*/
+
+ immediate:
+ if(*s==' ')
+ s++;
+ if (strncmp(s, "ha%", 3) == 0) {
+ the_insn.highlow = HIGHADJ;
+ s += 3;
+ } else if (strncmp(s, "h%", 2) == 0) {
+ the_insn.highlow = HIGH;
+ s += 2;
+ } else if (strncmp(s, "l%", 2) == 0) {
+ the_insn.highlow = PAIR;
+ s += 2;
+ }
+ the_insn.expand = insn->expand;
+
+ /* Note that if the getExpression() fails, we will still have
+ created U entries in the symbol table for the 'symbols'
+ in the input string. Try not to create U symbols for
+ registers, etc. */
+
+ if ( !getExpression(s)) {
+ s = expr_end;
+ continue;
+ }
+ break;
+
+ default:
+ abort();
+ }
+ break;
+ }
+ error:
+ if (match == FALSE)
+ {
+ /* Args don't match. */
+ if (&insn[1] - i860_opcodes < NUMOPCODES
+ && !strcmp(insn->name, insn[1].name))
+ {
+ ++insn;
+ s = argsStart;
+ continue;
+ }
+ else
+ {
+ as_warn("Illegal operands");
+ return;
+ }
+ }
+ break;
+ }
+
+ the_insn.opcode = opcode;
+ return;
+}
+
+static int
+getExpression(str)
+ char *str;
+{
+ char *save_in;
+ segT seg;
+
+ save_in = input_line_pointer;
+ input_line_pointer = str;
+ switch (seg = expression(&the_insn.exp)) {
+
+ case SEG_ABSOLUTE:
+ case SEG_TEXT:
+ case SEG_DATA:
+ case SEG_BSS:
+ case SEG_UNKNOWN:
+ case SEG_DIFFERENCE:
+ case SEG_BIG:
+ case SEG_NONE:
+ break;
+
+ default:
+ the_insn.error = "bad segment";
+ expr_end = input_line_pointer;
+ input_line_pointer=save_in;
+ return 1;
+ }
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+ return 0;
+}
+
+
+/*
+ This is identical to the md_atof in m68k.c. I think this is right,
+ but I'm not sure.
+
+ Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof(type,litP,sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+ char *atof_ieee();
+
+ switch(type) {
+
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP=0;
+ return "Bad call to MD_ATOF()";
+ }
+ t=atof_ieee(input_line_pointer,type,words);
+ if(t)
+ input_line_pointer=t;
+ *sizeP=prec * sizeof(LITTLENUM_TYPE);
+ for(wordP=words;prec--;) {
+ md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
+ litP+=sizeof(LITTLENUM_TYPE);
+ }
+ return ""; /* Someone should teach Dean about null pointers */
+}
+
+/*
+ * Write out big-endian.
+ */
+void
+md_number_to_chars(buf,val,n)
+ char *buf;
+ long val;
+ int n;
+{
+ switch(n) {
+
+ case 4:
+ *buf++ = val >> 24;
+ *buf++ = val >> 16;
+ case 2:
+ *buf++ = val >> 8;
+ case 1:
+ *buf = val;
+ break;
+
+ default:
+ abort();
+ }
+ return;
+}
+
+void
+md_number_to_imm(buf,val,n, fixP, seg_type)
+ char *buf;
+ long val;
+ int n;
+ fixS *fixP;
+ int seg_type;
+{
+ enum reloc_type reloc = fixP->fx_r_type & 0xf;
+ enum highlow_type highlow = (fixP->fx_r_type >> 4) & 0x3;
+
+ assert(buf);
+ assert(n == 4); /* always on i860 */
+
+ switch(highlow)
+ {
+
+ case HIGHADJ: /* adjusts the high-order 16-bits */
+ if (val & (1 << 15))
+ val += (1 << 16);
+
+ /*FALLTHROUGH*/
+
+ case HIGH: /* selects the high-order 16-bits */
+ val >>= 16;
+ break;
+
+ case PAIR: /* selects the low-order 16-bits */
+ val = val & 0xffff;
+ break;
+
+ default:
+ break;
+ }
+
+ switch(reloc)
+ {
+
+ case BRADDR: /* br,call,bc,bc.t,bnc,bnc.t w/26-bit immediate */
+ if (fixP->fx_pcrel != TRUE)
+ as_warn("26-bit branch w/o pc relative set: 0x%08x", val);
+ val >>= 2; /* align pcrel offset, see manual */
+
+ if (val >= (1 << 25) || val < -(1 << 25)) /* check for overflow */
+ as_warn("26-bit branch offset overflow: 0x%08x", val);
+ buf[0] = (buf[0] & 0xfc) | ((val >> 24) & 0x3);
+ buf[1] = val >> 16;
+ buf[2] = val >> 8;
+ buf[3] = val;
+ break;
+
+ case SPLIT2: /* 16 bit immediate, 4-byte aligned */
+ if (val & 0x3)
+ as_warn("16-bit immediate 4-byte alignment error: 0x%08x", val);
+ val &= ~0x3; /* 4-byte align value */
+ /*FALLTHROUGH*/
+ case SPLIT1: /* 16 bit immediate, 2-byte aligned */
+ if (val & 0x1)
+ as_warn("16-bit immediate 2-byte alignment error: 0x%08x", val);
+ val &= ~0x1; /* 2-byte align value */
+ /*FALLTHROUGH*/
+ case SPLIT0: /* st,bla,bte,btne w/16-bit immediate */
+ if (fixP->fx_pcrel == TRUE)
+ val >>= 2; /* align pcrel offset, see manual */
+ /* check for bounds */
+ if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15)))
+ as_warn("16-bit branch offset overflow: 0x%08x", val);
+ buf[1] = (buf[1] & ~0x1f) | ((val >> 11) & 0x1f);
+ buf[2] = (buf[2] & ~0x7) | ((val >> 8) & 0x7);
+ buf[3] |= val; /* perserve bottom opcode bits */
+ break;
+
+ case LOW4: /* fld,pfld,pst,flush 16-byte aligned */
+ if (val & 0xf)
+ as_warn("16-bit immediate 16-byte alignment error: 0x%08x", val);
+ val &= ~0xf; /* 16-byte align value */
+ /*FALLTHROUGH*/
+ case LOW3: /* fld,pfld,pst,flush 8-byte aligned */
+ if (val & 0x7)
+ as_warn("16-bit immediate 8-byte alignment error: 0x%08x", val);
+ val &= ~0x7; /* 8-byte align value */
+ /*FALLTHROUGH*/
+ case LOW2: /* 16 bit immediate, 4-byte aligned */
+ if (val & 0x3)
+ as_warn("16-bit immediate 4-byte alignment error: 0x%08x", val);
+ val &= ~0x3; /* 4-byte align value */
+ /*FALLTHROUGH*/
+ case LOW1: /* 16 bit immediate, 2-byte aligned */
+ if (val & 0x1)
+ as_warn("16-bit immediate 2-byte alignment error: 0x%08x", val);
+ val &= ~0x1; /* 2-byte align value */
+ /*FALLTHROUGH*/
+ case LOW0: /* 16 bit immediate, byte aligned */
+ /* check for bounds */
+ if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15)))
+ as_warn("16-bit immediate overflow: 0x%08x", val);
+ buf[2] = val >> 8;
+ buf[3] |= val; /* perserve bottom opcode bits */
+ break;
+
+ case NO_RELOC:
+ default:
+ as_warn("bad relocation type: 0x%02x", reloc);
+ break;
+ }
+ return;
+}
+
+/* should never be called for i860 */
+void
+md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ long from_addr, to_addr;
+{
+ fprintf(stderr, "i860_create_short_jmp\n");
+ abort();
+}
+
+/* should never be called for i860 */
+void
+md_number_to_disp(buf,val,n)
+ char *buf;
+ long val;
+{
+ fprintf(stderr, "md_number_to_disp\n");
+ abort();
+}
+
+/* should never be called for i860 */
+void
+md_number_to_field(buf,val,fix)
+ char *buf;
+ long val;
+ void *fix;
+{
+ fprintf(stderr, "i860_number_to_field\n");
+ abort();
+}
+
+/* the bit-field entries in the relocation_info struct plays hell
+ with the byte-order problems of cross-assembly. So as a hack,
+ I added this mach. dependent ri twiddler. Ugly, but it gets
+ you there. -KWK */
+/* on i860: first 4 bytes are normal unsigned long address, next three
+ bytes are index, most sig. byte first. Byte 7 is broken up with
+ bit 7 as pcrel, bit 6 as extern, and the lower six bits as
+ relocation type (highlow 5-4). Next 4 bytes are long int addend. */
+/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
+void
+md_ri_to_chars(ri_p, ri)
+ struct relocation_info *ri_p, ri;
+{
+#if 0
+ unsigned char the_bytes[sizeof(*ri_p)];
+
+ /* this is easy */
+ md_number_to_chars(the_bytes, ri.r_address, sizeof(ri.r_address));
+ /* now the fun stuff */
+ the_bytes[4] = (ri.r_index >> 16) & 0x0ff;
+ the_bytes[5] = (ri.r_index >> 8) & 0x0ff;
+ the_bytes[6] = ri.r_index & 0x0ff;
+ the_bytes[7] = ((ri.r_extern << 7) & 0x80) | (0 & 0x60) | (ri.r_type & 0x1F);
+ /* Also easy */
+ md_number_to_chars(&the_bytes[8], ri.r_addend, sizeof(ri.r_addend));
+ /* now put it back where you found it, Junior... */
+ bcopy (the_bytes, (char *)ri_p, sizeof(*ri_p));
+#endif
+}
+
+/* should never be called for i860 */
+void
+md_convert_frag(fragP)
+ register fragS *fragP;
+{
+ fprintf(stderr, "i860_convert_frag\n");
+ abort();
+}
+
+/* should never be called for i860 */
+void
+md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ long from_addr,
+ to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ fprintf(stderr, "i860_create_long_jump\n");
+ abort();
+}
+
+/* should never be called for i860 */
+int
+md_estimate_size_before_relax(fragP, segtype)
+ register fragS *fragP;
+{
+ fprintf(stderr, "i860_estimate_size_before_relax\n");
+ abort();
+ return 0;
+}
+
+/* for debugging only, must match enum reloc_type */
+static char *Reloc[] = {
+ "NO_RELOC",
+ "BRADDR",
+ "LOW0",
+ "LOW1",
+ "LOW2",
+ "LOW3",
+ "LOW4",
+ "SPLIT0",
+ "SPLIT1",
+ "SPLIT2",
+ "RELOC_32",
+};
+static char *Highlow[] = {
+ "NO_SPEC",
+ "PAIR",
+ "HIGH",
+ "HIGHADJ",
+};
+static void
+print_insn(insn)
+ struct i860_it *insn;
+{
+ if (insn->error) {
+ fprintf(stderr, "ERROR: %s\n");
+ }
+ fprintf(stderr, "opcode=0x%08x\t", insn->opcode);
+ fprintf(stderr, "expand=0x%08x\t", insn->expand);
+ fprintf(stderr, "reloc = %s\t", Reloc[insn->reloc]);
+ fprintf(stderr, "highlow = %s\n", Highlow[insn->highlow]);
+ fprintf(stderr, "exp = {\n");
+ fprintf(stderr, "\t\tX_add_symbol = %s\n",
+ insn->exp.X_add_symbol ?
+ (insn->exp.X_add_symbol->sy_name ?
+ insn->exp.X_add_symbol->sy_name : "???") : "0");
+ fprintf(stderr, "\t\tX_sub_symbol = %s\n",
+ insn->exp.X_subtract_symbol ?
+ (insn->exp.X_subtract_symbol->sy_name ?
+ insn->exp.X_subtract_symbol->sy_name : "???") : "0");
+ fprintf(stderr, "\t\tX_add_number = %d\n",
+ insn->exp.X_add_number);
+ fprintf(stderr, "}\n");
+ return;
+}
+
+int
+md_parse_option(argP,cntP,vecP)
+ char **argP;
+ int *cntP;
+ char ***vecP;
+{
+ return 1;
+}
+
+/*
+ * I860 relocations are completely different, so it needs
+ * this machine dependent routine to emit them.
+ */
+void
+emit_relocations(fixP, segment_address_in_file)
+ register fixS *fixP;
+ relax_addressT segment_address_in_file;
+{
+ struct reloc_info_i860 ri;
+ register symbolS *symbolP;
+ extern char *next_object_file_charP;
+ long add_number;
+
+ bzero((char *) &ri, sizeof(ri));
+ for (; fixP; fixP = fixP->fx_next) {
+
+ if (fixP->fx_r_type & ~0x3f) {
+ fprintf(stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type);
+ abort();
+ }
+ ri.r_pcrel = fixP->fx_pcrel;
+ ri.r_type = fixP->fx_r_type;
+
+ if ((symbolP = fixP->fx_addsy) != NULL) {
+ ri.r_address = fixP->fx_frag->fr_address +
+ fixP->fx_where - segment_address_in_file;
+ if ((symbolP->sy_type & N_TYPE) == N_UNDF) {
+ ri.r_extern = 1;
+ ri.r_symbolnum = symbolP->sy_number;
+ } else {
+ ri.r_extern = 0;
+ ri.r_symbolnum = symbolP->sy_type & N_TYPE;
+ }
+ if (symbolP && symbolP->sy_frag) {
+ ri.r_addend = symbolP->sy_frag->fr_address;
+ }
+ ri.r_type = fixP->fx_r_type;
+ if (fixP->fx_pcrel) {
+ /* preserve actual offset vs. pc + 4 */
+ ri.r_addend -= (ri.r_address + 4);
+ } else {
+ ri.r_addend = fixP->fx_addnumber;
+ }
+
+ md_ri_to_chars((char *) &ri, ri);
+ append(&next_object_file_charP, (char *)& ri, sizeof(ri));
+ }
+ }
+ return;
+}
+
diff --git a/gnu/usr.bin/gas/config/i860.h b/gnu/usr.bin/gas/config/i860.h
new file mode 100644
index 00000000000..1abdedc8c42
--- /dev/null
+++ b/gnu/usr.bin/gas/config/i860.h
@@ -0,0 +1,48 @@
+/* i860.h -- Header file for the I860
+ Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+enum reloc_type /* NOTE: three bits max, see struct reloc_info_i860.r_type */
+{
+ NO_RELOC = 0, BRADDR, LOW0, LOW1, LOW2, LOW3, LOW4, SPLIT0, SPLIT1, SPLIT2, RELOC_32,
+};
+
+enum highlow_type /* NOTE: two bits max, see reloc_info_i860.r_type */
+{
+ NO_SPEC = 0, PAIR, HIGH, HIGHADJ,
+};
+
+struct reloc_info_i860
+{
+ unsigned long int r_address;
+/*
+ * Using bit fields here is a bad idea because the order is not portable. :-(
+ */
+ unsigned int r_symbolnum: 24;
+ unsigned int r_pcrel : 1;
+ unsigned int r_extern : 1;
+ /* combining the two field simplifies the argument passing in "new_fix()" */
+ /* and is compatible with the existing Sparc #ifdef's */
+ /* r_type: highlow_type - bits 5,4; reloc_type - bits 3-0 */
+ unsigned int r_type : 6;
+ long int r_addend;
+};
+
+#define relocation_info reloc_info_i860
+
+
diff --git a/gnu/usr.bin/gas/config/m-hpux.h b/gnu/usr.bin/gas/config/m-hpux.h
new file mode 100644
index 00000000000..d59ef84fcbd
--- /dev/null
+++ b/gnu/usr.bin/gas/config/m-hpux.h
@@ -0,0 +1,24 @@
+/* m-hpux.h -- Header to compile the 68020 assembler under HP-UX
+ Copyright (C) 1988 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* This header file contains the #defines specific
+ to HPUX changes sent me by cph@zurich.ai.mit.edu */
+#ifndef hpux
+#define hpux
+#endif
diff --git a/gnu/usr.bin/gas/config/m-sun3.h b/gnu/usr.bin/gas/config/m-sun3.h
new file mode 100644
index 00000000000..85a9554eb13
--- /dev/null
+++ b/gnu/usr.bin/gas/config/m-sun3.h
@@ -0,0 +1,31 @@
+/* m-sun3.h -- 68020 version of the assembler for the Sun-3
+ Copyright (C) 1987 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+
+/* This header file contains the #defines specific
+ to SUN computer SUN 3 series computers. (The only kind
+ we have around here, unfortunatly.)
+
+ Rumor has it that this file will work on the Sun-2 if the assembler
+ is called with -m68010 This is not tested. */
+
+
+#define M_SUN 1
+#define SUN_ASM_SYNTAX
diff --git a/gnu/usr.bin/gas/config/m68k-opcode.h b/gnu/usr.bin/gas/config/m68k-opcode.h
new file mode 100644
index 00000000000..e670cb83b54
--- /dev/null
+++ b/gnu/usr.bin/gas/config/m68k-opcode.h
@@ -0,0 +1,1680 @@
+/* Opcode table for m68000/m68020 and m68881.
+ Copyright (C) 1989, Free Software Foundation.
+
+This file is part of GDB, the GNU Debugger and GAS, the GNU Assembler.
+
+Both GDB and GAS are free software; you can redistribute and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB and GAS are distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB or GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+struct m68k_opcode
+{
+ char *name;
+ unsigned long opcode;
+ unsigned long match;
+ char *args;
+};
+
+/* We store four bytes of opcode for all opcodes because that
+ is the most any of them need. The actual length of an instruction
+ is always at least 2 bytes, and is as much longer as necessary to
+ hold the operands it has.
+
+ The match component is a mask saying which bits must match
+ particular opcode in order for an instruction to be an instance
+ of that opcode.
+
+ The args component is a string containing two characters
+ for each operand of the instruction. The first specifies
+ the kind of operand; the second, the place it is stored. */
+
+/* Kinds of operands:
+ D data register only. Stored as 3 bits.
+ A address register only. Stored as 3 bits.
+ R either kind of register. Stored as 4 bits.
+ F floating point coprocessor register only. Stored as 3 bits.
+ O an offset (or width): immediate data 0-31 or data register.
+ Stored as 6 bits in special format for BF... insns.
+ + autoincrement only. Stored as 3 bits (number of the address register).
+ - autodecrement only. Stored as 3 bits (number of the address register).
+ Q quick immediate data. Stored as 3 bits.
+ This matches an immediate operand only when value is in range 1 .. 8.
+ M moveq immediate data. Stored as 8 bits.
+ This matches an immediate operand only when value is in range -128..127
+ T trap vector immediate data. Stored as 4 bits.
+
+ k K-factor for fmove.p instruction. Stored as a 7-bit constant or
+ a three bit register offset, depending on the field type.
+
+ # immediate data. Stored in special places (b, w or l)
+ which say how many bits to store.
+ ^ immediate data for floating point instructions. Special places
+ are offset by 2 bytes from '#'...
+ B pc-relative address, converted to an offset
+ that is treated as immediate data.
+ d displacement and register. Stores the register as 3 bits
+ and stores the displacement in the entire second word.
+
+ C the CCR. No need to store it; this is just for filtering validity.
+ S the SR. No need to store, just as with CCR.
+ U the USP. No need to store, just as with CCR.
+
+ I Coprocessor ID. Not printed if 1. The Coprocessor ID is always
+ extracted from the 'd' field of word one, which means that an extended
+ coprocessor opcode can be skipped using the 'i' place, if needed.
+
+ s System Control register for the floating point coprocessor.
+ S List of system control registers for floating point coprocessor.
+
+ J Misc register for movec instruction, stored in 'j' format.
+ Possible values:
+ 000 SFC Source Function Code reg
+ 001 DFC Data Function Code reg
+ 002 CACR Cache Control Register
+ 800 USP User Stack Pointer
+ 801 VBR Vector Base reg
+ 802 CAAR Cache Address Register
+ 803 MSP Master Stack Pointer
+ 804 ISP Interrupt Stack Pointer
+
+ L Register list of the type d0-d7/a0-a7 etc.
+ (New! Improved! Can also hold fp0-fp7, as well!)
+ The assembler tries to see if the registers match the insn by
+ looking at where the insn wants them stored.
+
+ l Register list like L, but with all the bits reversed.
+ Used for going the other way. . .
+
+ They are all stored as 6 bits using an address mode and a register number;
+ they differ in which addressing modes they match.
+
+ * all (modes 0-6,7.*)
+ ~ alterable memory (modes 2-6,7.0,7.1)(not 0,1,7.~)
+ % alterable (modes 0-6,7.0,7.1)(not 7.~)
+ ; data (modes 0,2-6,7.*)(not 1)
+ @ data, but not immediate (modes 0,2-6,7.? ? ?)(not 1,7.?) This may really be ;, the 68020 book says it is
+ ! control (modes 2,5,6,7.*-)(not 0,1,3,4,7.4)
+ & alterable control (modes 2,5,6,7.0,7.1)(not 0,1,7.? ? ?)
+ $ alterable data (modes 0,2-6,7.0,7.1)(not 1,7.~)
+ ? alterable control, or data register (modes 0,2,5,6,7.0,7.1)(not 1,3,4,7.~)
+ / control, or data register (modes 0,2,5,6,7.0,7.1,7.2,7.3)(not 1,3,4,7.4)
+*/
+
+/* JF: for the 68851 */
+/*
+ I didn't use much imagination in choosing the
+ following codes, so many of them aren't very
+ mnemonic. -rab
+
+ P pmmu register
+ Possible values:
+ 000 TC Translation Control reg
+ 100 CAL Current Access Level
+ 101 VAL Validate Access Level
+ 110 SCC Stack Change Control
+ 111 AC Access Control
+
+ W wide pmmu registers
+ Possible values:
+ 001 DRP Dma Root Pointer
+ 010 SRP Supervisor Root Pointer
+ 011 CRP Cpu Root Pointer
+
+ f function code register
+ 0 SFC
+ 1 DFC
+
+ V VAL register only
+
+ X BADx, BACx
+ 100 BAD Breakpoint Acknowledge Data
+ 101 BAC Breakpoint Acknowledge Control
+
+ Y PSR
+ Z PCSR
+
+ | memory (modes 2-6, 7.*)
+
+*/
+
+/* Places to put an operand, for non-general operands:
+ s source, low bits of first word.
+ d dest, shifted 9 in first word
+ 1 second word, shifted 12
+ 2 second word, shifted 6
+ 3 second word, shifted 0
+ 4 third word, shifted 12
+ 5 third word, shifted 6
+ 6 third word, shifted 0
+ 7 second word, shifted 7
+ 8 second word, shifted 10
+ D store in both place 1 and place 3; for divul and divsl.
+ b second word, low byte
+ w second word (entire)
+ l second and third word (entire)
+ g branch offset for bra and similar instructions.
+ The place to store depends on the magnitude of offset.
+ t store in both place 7 and place 8; for floating point operations
+ c branch offset for cpBcc operations.
+ The place to store is word two if bit six of word one is zero,
+ and words two and three if bit six of word one is one.
+ i Increment by two, to skip over coprocessor extended operands. Only
+ works with the 'I' format.
+ k Dynamic K-factor field. Bits 6-4 of word 2, used as a register number.
+ Also used for dynamic fmovem instruction.
+ C floating point coprocessor constant - 7 bits. Also used for static
+ K-factors...
+ j Movec register #, stored in 12 low bits of second word.
+
+ Places to put operand, for general operands:
+ d destination, shifted 6 bits in first word
+ b source, at low bit of first word, and immediate uses one byte
+ w source, at low bit of first word, and immediate uses two bytes
+ l source, at low bit of first word, and immediate uses four bytes
+ s source, at low bit of first word.
+ Used sometimes in contexts where immediate is not allowed anyway.
+ f single precision float, low bit of 1st word, immediate uses 4 bytes
+ F double precision float, low bit of 1st word, immediate uses 8 bytes
+ x extended precision float, low bit of 1st word, immediate uses 12 bytes
+ p packed float, low bit of 1st word, immediate uses 12 bytes
+*/
+
+#define one(x) ((x) << 16)
+#define two(x, y) (((x) << 16) + y)
+
+/*
+ *** DANGER WILL ROBINSON ***
+
+ The assembler requires that all instances of the same mnemonic must be
+ consecutive. If they aren't, the assembler will bomb at runtime
+ */
+struct m68k_opcode m68k_opcodes[] =
+{
+{"abcd", one(0140400), one(0170770), "DsDd"},
+{"abcd", one(0140410), one(0170770), "-s-d"},
+
+ /* Add instructions */
+{"addal", one(0150700), one(0170700), "*lAd"},
+{"addaw", one(0150300), one(0170700), "*wAd"},
+{"addib", one(0003000), one(0177700), "#b$b"},
+{"addil", one(0003200), one(0177700), "#l$l"},
+{"addiw", one(0003100), one(0177700), "#w$w"},
+{"addqb", one(0050000), one(0170700), "Qd$b"},
+{"addql", one(0050200), one(0170700), "Qd%l"},
+{"addqw", one(0050100), one(0170700), "Qd%w"},
+
+{"addb", one(0050000), one(0170700), "Qd$b"}, /* addq written as add */
+{"addb", one(0003000), one(0177700), "#b$b"}, /* addi written as add */
+{"addb", one(0150000), one(0170700), ";bDd"}, /* addb <ea>, Dd */
+{"addb", one(0150400), one(0170700), "Dd~b"}, /* addb Dd, <ea> */
+
+{"addw", one(0050100), one(0170700), "Qd%w"}, /* addq written as add */
+{"addw", one(0003100), one(0177700), "#w$w"}, /* addi written as add */
+{"addw", one(0150300), one(0170700), "*wAd"}, /* adda written as add */
+{"addw", one(0150100), one(0170700), "*wDd"}, /* addw <ea>, Dd */
+{"addw", one(0150500), one(0170700), "Dd~w"}, /* addw Dd, <ea> */
+
+{"addl", one(0050200), one(0170700), "Qd%l"}, /* addq written as add */
+{"addl", one(0003200), one(0177700), "#l$l"}, /* addi written as add */
+{"addl", one(0150700), one(0170700), "*lAd"}, /* adda written as add */
+{"addl", one(0150200), one(0170700), "*lDd"}, /* addl <ea>, Dd */
+{"addl", one(0150600), one(0170700), "Dd~l"}, /* addl Dd, <ea> */
+
+{"addxb", one(0150400), one(0170770), "DsDd"},
+{"addxb", one(0150410), one(0170770), "-s-d"},
+{"addxl", one(0150600), one(0170770), "DsDd"},
+{"addxl", one(0150610), one(0170770), "-s-d"},
+{"addxw", one(0150500), one(0170770), "DsDd"},
+{"addxw", one(0150510), one(0170770), "-s-d"},
+
+{"andib", one(0001000), one(0177700), "#b$b"},
+{"andib", one(0001074), one(0177777), "#bCb"}, /* andi to ccr */
+{"andiw", one(0001100), one(0177700), "#w$w"},
+{"andiw", one(0001174), one(0177777), "#wSw"}, /* andi to sr */
+{"andil", one(0001200), one(0177700), "#l$l"},
+
+{"andb", one(0001000), one(0177700), "#b$b"}, /* andi written as or */
+{"andb", one(0001074), one(0177777), "#bCb"}, /* andi to ccr */
+{"andb", one(0140000), one(0170700), ";bDd"}, /* memory to register */
+{"andb", one(0140400), one(0170700), "Dd~b"}, /* register to memory */
+{"andw", one(0001100), one(0177700), "#w$w"}, /* andi written as or */
+{"andw", one(0001174), one(0177777), "#wSw"}, /* andi to sr */
+{"andw", one(0140100), one(0170700), ";wDd"}, /* memory to register */
+{"andw", one(0140500), one(0170700), "Dd~w"}, /* register to memory */
+{"andl", one(0001200), one(0177700), "#l$l"}, /* andi written as or */
+{"andl", one(0140200), one(0170700), ";lDd"}, /* memory to register */
+{"andl", one(0140600), one(0170700), "Dd~l"}, /* register to memory */
+
+{"aslb", one(0160400), one(0170770), "QdDs"},
+{"aslb", one(0160440), one(0170770), "DdDs"},
+{"asll", one(0160600), one(0170770), "QdDs"},
+{"asll", one(0160640), one(0170770), "DdDs"},
+{"aslw", one(0160500), one(0170770), "QdDs"},
+{"aslw", one(0160540), one(0170770), "DdDs"},
+{"aslw", one(0160700), one(0177700), "~s"}, /* Shift memory */
+{"asrb", one(0160000), one(0170770), "QdDs"},
+{"asrb", one(0160040), one(0170770), "DdDs"},
+{"asrl", one(0160200), one(0170770), "QdDs"},
+{"asrl", one(0160240), one(0170770), "DdDs"},
+{"asrw", one(0160100), one(0170770), "QdDs"},
+{"asrw", one(0160140), one(0170770), "DdDs"},
+{"asrw", one(0160300), one(0177700), "~s"}, /* Shift memory */
+
+{"bhi", one(0061000), one(0177400), "Bg"},
+{"bls", one(0061400), one(0177400), "Bg"},
+{"bcc", one(0062000), one(0177400), "Bg"},
+{"bcs", one(0062400), one(0177400), "Bg"},
+{"bne", one(0063000), one(0177400), "Bg"},
+{"beq", one(0063400), one(0177400), "Bg"},
+{"bvc", one(0064000), one(0177400), "Bg"},
+{"bvs", one(0064400), one(0177400), "Bg"},
+{"bpl", one(0065000), one(0177400), "Bg"},
+{"bmi", one(0065400), one(0177400), "Bg"},
+{"bge", one(0066000), one(0177400), "Bg"},
+{"blt", one(0066400), one(0177400), "Bg"},
+{"bgt", one(0067000), one(0177400), "Bg"},
+{"ble", one(0067400), one(0177400), "Bg"},
+
+{"bchg", one(0000500), one(0170700), "Dd$s"},
+{"bchg", one(0004100), one(0177700), "#b$s"},
+{"bclr", one(0000600), one(0170700), "Dd$s"},
+{"bclr", one(0004200), one(0177700), "#b$s"},
+{"bfchg", two(0165300, 0), two(0177700, 0170000), "?sO2O3"},
+{"bfclr", two(0166300, 0), two(0177700, 0170000), "?sO2O3"},
+{"bfexts", two(0165700, 0), two(0177700, 0100000), "/sO2O3D1"},
+{"bfextu", two(0164700, 0), two(0177700, 0100000), "/sO2O3D1"},
+{"bfffo", two(0166700, 0), two(0177700, 0100000), "/sO2O3D1"},
+{"bfins", two(0167700, 0), two(0177700, 0100000), "D1?sO2O3"},
+{"bfset", two(0167300, 0), two(0177700, 0170000), "?sO2O3"},
+{"bftst", two(0164300, 0), two(0177700, 0170000), "/sO2O3"},
+{"bset", one(0000700), one(0170700), "Dd$s"},
+{"bset", one(0004300), one(0177700), "#b$s"},
+{"btst", one(0000400), one(0170700), "Dd@s"},
+{"btst", one(0004000), one(0177700), "#b@s"},
+
+{"bkpt", one(0044110), one(0177770), "Qs"},
+{"bra", one(0060000), one(0177400), "Bg"},
+{"bras", one(0060000), one(0177400), "Bw"},
+{"bsr", one(0060400), one(0177400), "Bg"},
+{"bsrs", one(0060400), one(0177400), "Bw"},
+
+{"callm", one(0003300), one(0177700), "#b!s"},
+{"cas2l", two(0007374, 0), two(0177777, 0107070), "D3D6D2D5R1R4"}, /* JF FOO this is really a 3 word ins */
+{"cas2w", two(0006374, 0), two(0177777, 0107070), "D3D6D2D5R1R4"}, /* JF ditto */
+{"casb", two(0005300, 0), two(0177700, 0177070), "D3D2~s"},
+{"casl", two(0007300, 0), two(0177700, 0177070), "D3D2~s"},
+{"casw", two(0006300, 0), two(0177700, 0177070), "D3D2~s"},
+
+/* {"chk", one(0040600), one(0170700), ";wDd"}, JF FOO this looks wrong */
+{"chk2b", two(0000300, 0004000), two(0177700, 07777), "!sR1"},
+{"chk2l", two(0002300, 0004000), two(0177700, 07777), "!sR1"},
+{"chk2w", two(0001300, 0004000), two(0177700, 07777), "!sR1"},
+{"chkl", one(0040400), one(0170700), ";lDd"},
+{"chkw", one(0040600), one(0170700), ";wDd"},
+{"clrb", one(0041000), one(0177700), "$s"},
+{"clrl", one(0041200), one(0177700), "$s"},
+{"clrw", one(0041100), one(0177700), "$s"},
+
+{"cmp2b", two(0000300, 0), two(0177700, 07777), "!sR1"},
+{"cmp2l", two(0002300, 0), two(0177700, 07777), "!sR1"},
+{"cmp2w", two(0001300, 0), two(0177700, 07777), "!sR1"},
+{"cmpal", one(0130700), one(0170700), "*lAd"},
+{"cmpaw", one(0130300), one(0170700), "*wAd"},
+{"cmpib", one(0006000), one(0177700), "#b;b"},
+{"cmpil", one(0006200), one(0177700), "#l;l"},
+{"cmpiw", one(0006100), one(0177700), "#w;w"},
+{"cmpb", one(0006000), one(0177700), "#b;b"}, /* cmpi written as cmp */
+{"cmpb", one(0130000), one(0170700), ";bDd"},
+{"cmpw", one(0006100), one(0177700), "#w;w"},
+{"cmpw", one(0130100), one(0170700), "*wDd"},
+{"cmpw", one(0130300), one(0170700), "*wAd"}, /* cmpa written as cmp */
+{"cmpl", one(0006200), one(0177700), "#l;l"},
+{"cmpl", one(0130200), one(0170700), "*lDd"},
+{"cmpl", one(0130700), one(0170700), "*lAd"},
+{"cmpmb", one(0130410), one(0170770), "+s+d"},
+{"cmpml", one(0130610), one(0170770), "+s+d"},
+{"cmpmw", one(0130510), one(0170770), "+s+d"},
+
+{"dbcc", one(0052310), one(0177770), "DsBw"},
+{"dbcs", one(0052710), one(0177770), "DsBw"},
+{"dbeq", one(0053710), one(0177770), "DsBw"},
+{"dbf", one(0050710), one(0177770), "DsBw"},
+{"dbge", one(0056310), one(0177770), "DsBw"},
+{"dbgt", one(0057310), one(0177770), "DsBw"},
+{"dbhi", one(0051310), one(0177770), "DsBw"},
+{"dble", one(0057710), one(0177770), "DsBw"},
+{"dbls", one(0051710), one(0177770), "DsBw"},
+{"dblt", one(0056710), one(0177770), "DsBw"},
+{"dbmi", one(0055710), one(0177770), "DsBw"},
+{"dbne", one(0053310), one(0177770), "DsBw"},
+{"dbpl", one(0055310), one(0177770), "DsBw"},
+{"dbra", one(0050710), one(0177770), "DsBw"},
+{"dbt", one(0050310), one(0177770), "DsBw"},
+{"dbvc", one(0054310), one(0177770), "DsBw"},
+{"dbvs", one(0054710), one(0177770), "DsBw"},
+
+{"divsl", two(0046100, 0006000), two(0177700, 0107770), ";lD3D1"},
+{"divsl", two(0046100, 0004000), two(0177700, 0107770), ";lDD"},
+{"divsll", two(0046100, 0004000), two(0177700, 0107770), ";lD3D1"},
+{"divsw", one(0100700), one(0170700), ";wDd"},
+{"divs", one(0100700), one(0170700), ";wDd"},
+{"divul", two(0046100, 0002000), two(0177700, 0107770), ";lD3D1"},
+{"divul", two(0046100, 0000000), two(0177700, 0107770), ";lDD"},
+{"divull", two(0046100, 0000000), two(0177700, 0107770), ";lD3D1"},
+{"divuw", one(0100300), one(0170700), ";wDd"},
+{"divu", one(0100300), one(0170700), ";wDd"},
+{"eorb", one(0005000), one(0177700), "#b$s"}, /* eori written as or */
+{"eorb", one(0005074), one(0177777), "#bCs"}, /* eori to ccr */
+{"eorb", one(0130400), one(0170700), "Dd$s"}, /* register to memory */
+{"eorib", one(0005000), one(0177700), "#b$s"},
+{"eorib", one(0005074), one(0177777), "#bCs"}, /* eori to ccr */
+{"eoril", one(0005200), one(0177700), "#l$s"},
+{"eoriw", one(0005100), one(0177700), "#w$s"},
+{"eoriw", one(0005174), one(0177777), "#wSs"}, /* eori to sr */
+{"eorl", one(0005200), one(0177700), "#l$s"},
+{"eorl", one(0130600), one(0170700), "Dd$s"},
+{"eorw", one(0005100), one(0177700), "#w$s"},
+{"eorw", one(0005174), one(0177777), "#wSs"}, /* eori to sr */
+{"eorw", one(0130500), one(0170700), "Dd$s"},
+
+{"exg", one(0140500), one(0170770), "DdDs"},
+{"exg", one(0140510), one(0170770), "AdAs"},
+{"exg", one(0140610), one(0170770), "DdAs"},
+{"exg", one(0140610), one(0170770), "AsDd"},
+
+{"extw", one(0044200), one(0177770), "Ds"},
+{"extl", one(0044300), one(0177770), "Ds"},
+{"extbl", one(0044700), one(0177770), "Ds"},
+{"extb.l", one(0044700), one(0177770), "Ds"}, /* Not sure we should support this one*/
+
+{"illegal", one(0045374), one(0177777), ""},
+{"jmp", one(0047300), one(0177700), "!s"},
+{"jsr", one(0047200), one(0177700), "!s"},
+{"lea", one(0040700), one(0170700), "!sAd"},
+{"linkw", one(0047120), one(0177770), "As#w"},
+{"linkl", one(0044010), one(0177770), "As#l"},
+{"link", one(0047120), one(0177770), "As#w"},
+{"link", one(0044010), one(0177770), "As#l"},
+
+{"lslb", one(0160410), one(0170770), "QdDs"}, /* lsrb #Q, Ds */
+{"lslb", one(0160450), one(0170770), "DdDs"}, /* lsrb Dd, Ds */
+{"lslw", one(0160510), one(0170770), "QdDs"}, /* lsrb #Q, Ds */
+{"lslw", one(0160550), one(0170770), "DdDs"}, /* lsrb Dd, Ds */
+{"lslw", one(0161700), one(0177700), "~s"}, /* Shift memory */
+{"lsll", one(0160610), one(0170770), "QdDs"}, /* lsrb #Q, Ds */
+{"lsll", one(0160650), one(0170770), "DdDs"}, /* lsrb Dd, Ds */
+
+{"lsrb", one(0160010), one(0170770), "QdDs"} /* lsrb #Q, Ds */,
+{"lsrb", one(0160050), one(0170770), "DdDs"}, /* lsrb Dd, Ds */
+{"lsrl", one(0160210), one(0170770), "QdDs"}, /* lsrb #Q, Ds */
+{"lsrl", one(0160250), one(0170770), "DdDs"}, /* lsrb #Q, Ds */
+{"lsrw", one(0160110), one(0170770), "QdDs"}, /* lsrb #Q, Ds */
+{"lsrw", one(0160150), one(0170770), "DdDs"}, /* lsrb #Q, Ds */
+{"lsrw", one(0161300), one(0177700), "~s"}, /* Shift memory */
+
+{"moveal", one(0020100), one(0170700), "*lAd"},
+{"moveaw", one(0030100), one(0170700), "*wAd"},
+{"moveb", one(0010000), one(0170000), ";b$d"}, /* move */
+{"movel", one(0070000), one(0170400), "MsDd"}, /* moveq written as move */
+{"movel", one(0020000), one(0170000), "*l$d"},
+{"movel", one(0020100), one(0170700), "*lAd"},
+{"movel", one(0047140), one(0177770), "AsUd"}, /* move to USP */
+{"movel", one(0047150), one(0177770), "UdAs"}, /* move from USP */
+
+{"movec", one(0047173), one(0177777), "R1Jj"},
+{"movec", one(0047173), one(0177777), "R1#j"},
+{"movec", one(0047172), one(0177777), "JjR1"},
+{"movec", one(0047172), one(0177777), "#jR1"},
+
+/* JF added these next four for the assembler */
+{"moveml", one(0044300), one(0177700), "Lw&s"}, /* movem reg to mem. */
+{"moveml", one(0044340), one(0177770), "lw-s"}, /* movem reg to autodecrement. */
+{"moveml", one(0046300), one(0177700), "!sLw"}, /* movem mem to reg. */
+{"moveml", one(0046330), one(0177770), "+sLw"}, /* movem autoinc to reg. */
+
+{"moveml", one(0044300), one(0177700), "#w&s"}, /* movem reg to mem. */
+{"moveml", one(0044340), one(0177770), "#w-s"}, /* movem reg to autodecrement. */
+{"moveml", one(0046300), one(0177700), "!s#w"}, /* movem mem to reg. */
+{"moveml", one(0046330), one(0177770), "+s#w"}, /* movem autoinc to reg. */
+
+/* JF added these next four for the assembler */
+{"movemw", one(0044200), one(0177700), "Lw&s"}, /* movem reg to mem. */
+{"movemw", one(0044240), one(0177770), "lw-s"}, /* movem reg to autodecrement. */
+{"movemw", one(0046200), one(0177700), "!sLw"}, /* movem mem to reg. */
+{"movemw", one(0046230), one(0177770), "+sLw"}, /* movem autoinc to reg. */
+
+{"movemw", one(0044200), one(0177700), "#w&s"}, /* movem reg to mem. */
+{"movemw", one(0044240), one(0177770), "#w-s"}, /* movem reg to autodecrement. */
+{"movemw", one(0046200), one(0177700), "!s#w"}, /* movem mem to reg. */
+{"movemw", one(0046230), one(0177770), "+s#w"}, /* movem autoinc to reg. */
+
+{"movepl", one(0000510), one(0170770), "dsDd"}, /* memory to register */
+{"movepl", one(0000710), one(0170770), "Ddds"}, /* register to memory */
+{"movepw", one(0000410), one(0170770), "dsDd"}, /* memory to register */
+{"movepw", one(0000610), one(0170770), "Ddds"}, /* register to memory */
+{"moveq", one(0070000), one(0170400), "MsDd"},
+{"movew", one(0030000), one(0170000), "*w$d"},
+{"movew", one(0030100), one(0170700), "*wAd"}, /* movea, written as move */
+{"movew", one(0040300), one(0177700), "Ss$s"}, /* Move from sr */
+{"movew", one(0041300), one(0177700), "Cs$s"}, /* Move from ccr */
+{"movew", one(0042300), one(0177700), ";wCd"}, /* move to ccr */
+{"movew", one(0043300), one(0177700), ";wSd"}, /* move to sr */
+
+{"movesb", two(0007000, 0), two(0177700, 07777), "~sR1"}, /* moves from memory */
+{"movesb", two(0007000, 04000), two(0177700, 07777), "R1~s"}, /* moves to memory */
+{"movesl", two(0007200, 0), two(0177700, 07777), "~sR1"}, /* moves from memory */
+{"movesl", two(0007200, 04000), two(0177700, 07777), "R1~s"}, /* moves to memory */
+{"movesw", two(0007100, 0), two(0177700, 07777), "~sR1"}, /* moves from memory */
+{"movesw", two(0007100, 04000), two(0177700, 07777), "R1~s"}, /* moves to memory */
+
+{"mulsl", two(0046000, 004000), two(0177700, 0107770), ";lD1"},
+{"mulsl", two(0046000, 006000), two(0177700, 0107770), ";lD3D1"},
+{"mulsw", one(0140700), one(0170700), ";wDd"},
+{"muls", one(0140700), one(0170700), ";wDd"},
+{"mulul", two(0046000, 000000), two(0177700, 0107770), ";lD1"},
+{"mulul", two(0046000, 002000), two(0177700, 0107770), ";lD3D1"},
+{"muluw", one(0140300), one(0170700), ";wDd"},
+{"mulu", one(0140300), one(0170700), ";wDd"},
+{"nbcd", one(0044000), one(0177700), "$s"},
+{"negb", one(0042000), one(0177700), "$s"},
+{"negl", one(0042200), one(0177700), "$s"},
+{"negw", one(0042100), one(0177700), "$s"},
+{"negxb", one(0040000), one(0177700), "$s"},
+{"negxl", one(0040200), one(0177700), "$s"},
+{"negxw", one(0040100), one(0177700), "$s"},
+{"nop", one(0047161), one(0177777), ""},
+{"notb", one(0043000), one(0177700), "$s"},
+{"notl", one(0043200), one(0177700), "$s"},
+{"notw", one(0043100), one(0177700), "$s"},
+
+{"orb", one(0000000), one(0177700), "#b$s"}, /* ori written as or */
+{"orb", one(0000074), one(0177777), "#bCs"}, /* ori to ccr */
+{"orb", one(0100000), one(0170700), ";bDd"}, /* memory to register */
+{"orb", one(0100400), one(0170700), "Dd~s"}, /* register to memory */
+{"orib", one(0000000), one(0177700), "#b$s"},
+{"orib", one(0000074), one(0177777), "#bCs"}, /* ori to ccr */
+{"oril", one(0000200), one(0177700), "#l$s"},
+{"oriw", one(0000100), one(0177700), "#w$s"},
+{"oriw", one(0000174), one(0177777), "#wSs"}, /* ori to sr */
+{"orl", one(0000200), one(0177700), "#l$s"},
+{"orl", one(0100200), one(0170700), ";lDd"}, /* memory to register */
+{"orl", one(0100600), one(0170700), "Dd~s"}, /* register to memory */
+{"orw", one(0000100), one(0177700), "#w$s"},
+{"orw", one(0000174), one(0177777), "#wSs"}, /* ori to sr */
+{"orw", one(0100100), one(0170700), ";wDd"}, /* memory to register */
+{"orw", one(0100500), one(0170700), "Dd~s"}, /* register to memory */
+
+{"pack", one(0100500), one(0170770), "DsDd#w"}, /* pack Ds, Dd, #w */
+{"pack", one(0100510), one(0170770), "-s-d#w"}, /* pack -(As), -(Ad), #w */
+{"pea", one(0044100), one(0177700), "!s"},
+{"reset", one(0047160), one(0177777), ""},
+
+{"rolb", one(0160430), one(0170770), "QdDs"}, /* rorb #Q, Ds */
+{"rolb", one(0160470), one(0170770), "DdDs"}, /* rorb Dd, Ds */
+{"roll", one(0160630), one(0170770), "QdDs"}, /* rorb #Q, Ds */
+{"roll", one(0160670), one(0170770), "DdDs"}, /* rorb Dd, Ds */
+{"rolw", one(0160530), one(0170770), "QdDs"}, /* rorb #Q, Ds */
+{"rolw", one(0160570), one(0170770), "DdDs"}, /* rorb Dd, Ds */
+{"rolw", one(0163700), one(0177700), "~s"}, /* Rotate memory */
+{"rorb", one(0160030), one(0170770), "QdDs"}, /* rorb #Q, Ds */
+{"rorb", one(0160070), one(0170770), "DdDs"}, /* rorb Dd, Ds */
+{"rorl", one(0160230), one(0170770), "QdDs"}, /* rorb #Q, Ds */
+{"rorl", one(0160270), one(0170770), "DdDs"}, /* rorb Dd, Ds */
+{"rorw", one(0160130), one(0170770), "QdDs"}, /* rorb #Q, Ds */
+{"rorw", one(0160170), one(0170770), "DdDs"}, /* rorb Dd, Ds */
+{"rorw", one(0163300), one(0177700), "~s"}, /* Rotate memory */
+
+{"roxlb", one(0160420), one(0170770), "QdDs"}, /* roxrb #Q, Ds */
+{"roxlb", one(0160460), one(0170770), "DdDs"}, /* roxrb Dd, Ds */
+{"roxll", one(0160620), one(0170770), "QdDs"}, /* roxrb #Q, Ds */
+{"roxll", one(0160660), one(0170770), "DdDs"}, /* roxrb Dd, Ds */
+{"roxlw", one(0160520), one(0170770), "QdDs"}, /* roxrb #Q, Ds */
+{"roxlw", one(0160560), one(0170770), "DdDs"}, /* roxrb Dd, Ds */
+{"roxlw", one(0162700), one(0177700), "~s"}, /* Rotate memory */
+{"roxrb", one(0160020), one(0170770), "QdDs"}, /* roxrb #Q, Ds */
+{"roxrb", one(0160060), one(0170770), "DdDs"}, /* roxrb Dd, Ds */
+{"roxrl", one(0160220), one(0170770), "QdDs"}, /* roxrb #Q, Ds */
+{"roxrl", one(0160260), one(0170770), "DdDs"}, /* roxrb Dd, Ds */
+{"roxrw", one(0160120), one(0170770), "QdDs"}, /* roxrb #Q, Ds */
+{"roxrw", one(0160160), one(0170770), "DdDs"}, /* roxrb Dd, Ds */
+{"roxrw", one(0162300), one(0177700), "~s"}, /* Rotate memory */
+
+{"rtd", one(0047164), one(0177777), "#w"},
+{"rte", one(0047163), one(0177777), ""},
+{"rtm", one(0003300), one(0177760), "Rs"},
+{"rtr", one(0047167), one(0177777), ""},
+{"rts", one(0047165), one(0177777), ""},
+
+{"scc", one(0052300), one(0177700), "$s"},
+{"scs", one(0052700), one(0177700), "$s"},
+{"seq", one(0053700), one(0177700), "$s"},
+{"sf", one(0050700), one(0177700), "$s"},
+{"sge", one(0056300), one(0177700), "$s"},
+{"sgt", one(0057300), one(0177700), "$s"},
+{"shi", one(0051300), one(0177700), "$s"},
+{"sle", one(0057700), one(0177700), "$s"},
+{"sls", one(0051700), one(0177700), "$s"},
+{"slt", one(0056700), one(0177700), "$s"},
+{"smi", one(0055700), one(0177700), "$s"},
+{"sne", one(0053300), one(0177700), "$s"},
+{"spl", one(0055300), one(0177700), "$s"},
+{"st", one(0050300), one(0177700), "$s"},
+{"svc", one(0054300), one(0177700), "$s"},
+{"svs", one(0054700), one(0177700), "$s"},
+
+{"sbcd", one(0100400), one(0170770), "DsDd"},
+{"sbcd", one(0100410), one(0170770), "-s-d"},
+{"stop", one(0047162), one(0177777), "#w"},
+
+{"subal", one(0110700), one(0170700), "*lAd"},
+{"subaw", one(0110300), one(0170700), "*wAd"},
+{"subb", one(0050400), one(0170700), "Qd%s"}, /* subq written as sub */
+{"subb", one(0002000), one(0177700), "#b$s"}, /* subi written as sub */
+{"subb", one(0110000), one(0170700), ";bDd"}, /* subb ? ?, Dd */
+{"subb", one(0110400), one(0170700), "Dd~s"}, /* subb Dd, ? ? */
+{"subib", one(0002000), one(0177700), "#b$s"},
+{"subil", one(0002200), one(0177700), "#l$s"},
+{"subiw", one(0002100), one(0177700), "#w$s"},
+{"subl", one(0050600), one(0170700), "Qd%s"},
+{"subl", one(0002200), one(0177700), "#l$s"},
+{"subl", one(0110700), one(0170700), "*lAd"},
+{"subl", one(0110200), one(0170700), "*lDd"},
+{"subl", one(0110600), one(0170700), "Dd~s"},
+{"subqb", one(0050400), one(0170700), "Qd%s"},
+{"subql", one(0050600), one(0170700), "Qd%s"},
+{"subqw", one(0050500), one(0170700), "Qd%s"},
+{"subw", one(0050500), one(0170700), "Qd%s"},
+{"subw", one(0002100), one(0177700), "#w$s"},
+{"subw", one(0110100), one(0170700), "*wDd"},
+{"subw", one(0110300), one(0170700), "*wAd"}, /* suba written as sub */
+{"subw", one(0110500), one(0170700), "Dd~s"},
+{"subxb", one(0110400), one(0170770), "DsDd"}, /* subxb Ds, Dd */
+{"subxb", one(0110410), one(0170770), "-s-d"}, /* subxb -(As), -(Ad) */
+{"subxl", one(0110600), one(0170770), "DsDd"},
+{"subxl", one(0110610), one(0170770), "-s-d"},
+{"subxw", one(0110500), one(0170770), "DsDd"},
+{"subxw", one(0110510), one(0170770), "-s-d"},
+
+{"swap", one(0044100), one(0177770), "Ds"},
+
+{"tas", one(0045300), one(0177700), "$s"},
+{"trap", one(0047100), one(0177760), "Ts"},
+
+{"trapcc", one(0052374), one(0177777), ""},
+{"trapcs", one(0052774), one(0177777), ""},
+{"trapeq", one(0053774), one(0177777), ""},
+{"trapf", one(0050774), one(0177777), ""},
+{"trapge", one(0056374), one(0177777), ""},
+{"trapgt", one(0057374), one(0177777), ""},
+{"traphi", one(0051374), one(0177777), ""},
+{"traple", one(0057774), one(0177777), ""},
+{"trapls", one(0051774), one(0177777), ""},
+{"traplt", one(0056774), one(0177777), ""},
+{"trapmi", one(0055774), one(0177777), ""},
+{"trapne", one(0053374), one(0177777), ""},
+{"trappl", one(0055374), one(0177777), ""},
+{"trapt", one(0050374), one(0177777), ""},
+{"trapvc", one(0054374), one(0177777), ""},
+{"trapvs", one(0054774), one(0177777), ""},
+
+{"trapcc.w", one(0052372), one(0177777), ""},
+{"trapcs.w", one(0052772), one(0177777), ""},
+{"trapeq.w", one(0053772), one(0177777), ""},
+{"trapf.w", one(0050772), one(0177777), ""},
+{"trapge.w", one(0056372), one(0177777), ""},
+{"trapgt.w", one(0057372), one(0177777), ""},
+{"traphi.w", one(0051372), one(0177777), ""},
+{"traple.w", one(0057772), one(0177777), ""},
+{"trapls.w", one(0051772), one(0177777), ""},
+{"traplt.w", one(0056772), one(0177777), ""},
+{"trapmi.w", one(0055772), one(0177777), ""},
+{"trapne.w", one(0053372), one(0177777), ""},
+{"trappl.w", one(0055372), one(0177777), ""},
+{"trapt.w", one(0050372), one(0177777), ""},
+{"trapvc.w", one(0054372), one(0177777), ""},
+{"trapvs.w", one(0054772), one(0177777), ""},
+
+{"trapcc.l", one(0052373), one(0177777), ""},
+{"trapcs.l", one(0052773), one(0177777), ""},
+{"trapeq.l", one(0053773), one(0177777), ""},
+{"trapf.l", one(0050773), one(0177777), ""},
+{"trapge.l", one(0056373), one(0177777), ""},
+{"trapgt.l", one(0057373), one(0177777), ""},
+{"traphi.l", one(0051373), one(0177777), ""},
+{"traple.l", one(0057773), one(0177777), ""},
+{"trapls.l", one(0051773), one(0177777), ""},
+{"traplt.l", one(0056773), one(0177777), ""},
+{"trapmi.l", one(0055773), one(0177777), ""},
+{"trapne.l", one(0053373), one(0177777), ""},
+{"trappl.l", one(0055373), one(0177777), ""},
+{"trapt.l", one(0050373), one(0177777), ""},
+{"trapvc.l", one(0054373), one(0177777), ""},
+{"trapvs.l", one(0054773), one(0177777), ""},
+
+{"trapv", one(0047166), one(0177777), ""},
+
+{"tstb", one(0045000), one(0177700), ";b"},
+{"tstw", one(0045100), one(0177700), "*w"},
+{"tstl", one(0045200), one(0177700), "*l"},
+
+{"unlk", one(0047130), one(0177770), "As"},
+{"unpk", one(0100600), one(0170770), "DsDd#w"},
+{"unpk", one(0100610), one(0170770), "-s-d#w"},
+ /* JF floating pt stuff moved down here */
+
+{"fabsb", two(0xF000, 0x5818), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fabsd", two(0xF000, 0x5418), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fabsl", two(0xF000, 0x4018), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fabsp", two(0xF000, 0x4C18), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fabss", two(0xF000, 0x4418), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fabsw", two(0xF000, 0x5018), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fabsx", two(0xF000, 0x0018), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fabsx", two(0xF000, 0x4818), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fabsx", two(0xF000, 0x0018), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"facosb", two(0xF000, 0x581C), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"facosd", two(0xF000, 0x541C), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"facosl", two(0xF000, 0x401C), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"facosp", two(0xF000, 0x4C1C), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"facoss", two(0xF000, 0x441C), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"facosw", two(0xF000, 0x501C), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"facosx", two(0xF000, 0x001C), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"facosx", two(0xF000, 0x481C), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"facosx", two(0xF000, 0x001C), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"faddb", two(0xF000, 0x5822), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"faddd", two(0xF000, 0x5422), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"faddl", two(0xF000, 0x4022), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"faddp", two(0xF000, 0x4C22), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fadds", two(0xF000, 0x4422), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"faddw", two(0xF000, 0x5022), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"faddx", two(0xF000, 0x0022), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"faddx", two(0xF000, 0x4822), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+/* {"faddx", two(0xF000, 0x0022), two(0xF1C0, 0xE07F), "IiFt"}, JF removed */
+
+{"fasinb", two(0xF000, 0x580C), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fasind", two(0xF000, 0x540C), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fasinl", two(0xF000, 0x400C), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fasinp", two(0xF000, 0x4C0C), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fasins", two(0xF000, 0x440C), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fasinw", two(0xF000, 0x500C), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fasinx", two(0xF000, 0x000C), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fasinx", two(0xF000, 0x480C), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fasinx", two(0xF000, 0x000C), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fatanb", two(0xF000, 0x580A), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fatand", two(0xF000, 0x540A), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fatanl", two(0xF000, 0x400A), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fatanp", two(0xF000, 0x4C0A), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fatans", two(0xF000, 0x440A), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fatanw", two(0xF000, 0x500A), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fatanx", two(0xF000, 0x000A), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fatanx", two(0xF000, 0x480A), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fatanx", two(0xF000, 0x000A), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fatanhb", two(0xF000, 0x580D), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fatanhd", two(0xF000, 0x540D), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fatanhl", two(0xF000, 0x400D), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fatanhp", two(0xF000, 0x4C0D), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fatanhs", two(0xF000, 0x440D), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fatanhw", two(0xF000, 0x500D), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fatanhx", two(0xF000, 0x000D), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fatanhx", two(0xF000, 0x480D), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fatanhx", two(0xF000, 0x000D), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fbeq", one(0xF081), one(0xF1BF), "IdBc"},
+{"fbf", one(0xF080), one(0xF1BF), "IdBc"},
+{"fbge", one(0xF093), one(0xF1BF), "IdBc"},
+{"fbgl", one(0xF096), one(0xF1BF), "IdBc"},
+{"fbgle", one(0xF097), one(0xF1BF), "IdBc"},
+{"fbgt", one(0xF092), one(0xF1BF), "IdBc"},
+{"fble", one(0xF095), one(0xF1BF), "IdBc"},
+{"fblt", one(0xF094), one(0xF1BF), "IdBc"},
+{"fbne", one(0xF08E), one(0xF1BF), "IdBc"},
+{"fbnge", one(0xF09C), one(0xF1BF), "IdBc"},
+{"fbngl", one(0xF099), one(0xF1BF), "IdBc"},
+{"fbngle", one(0xF098), one(0xF1BF), "IdBc"},
+{"fbngt", one(0xF09D), one(0xF1BF), "IdBc"},
+{"fbnle", one(0xF09A), one(0xF1BF), "IdBc"},
+{"fbnlt", one(0xF09B), one(0xF1BF), "IdBc"},
+{"fboge", one(0xF083), one(0xF1BF), "IdBc"},
+{"fbogl", one(0xF086), one(0xF1BF), "IdBc"},
+{"fbogt", one(0xF082), one(0xF1BF), "IdBc"},
+{"fbole", one(0xF085), one(0xF1BF), "IdBc"},
+{"fbolt", one(0xF084), one(0xF1BF), "IdBc"},
+{"fbor", one(0xF087), one(0xF1BF), "IdBc"},
+{"fbseq", one(0xF091), one(0xF1BF), "IdBc"},
+{"fbsf", one(0xF090), one(0xF1BF), "IdBc"},
+{"fbsne", one(0xF09E), one(0xF1BF), "IdBc"},
+{"fbst", one(0xF09F), one(0xF1BF), "IdBc"},
+{"fbt", one(0xF08F), one(0xF1BF), "IdBc"},
+{"fbueq", one(0xF089), one(0xF1BF), "IdBc"},
+{"fbuge", one(0xF08B), one(0xF1BF), "IdBc"},
+{"fbugt", one(0xF08A), one(0xF1BF), "IdBc"},
+{"fbule", one(0xF08D), one(0xF1BF), "IdBc"},
+{"fbult", one(0xF08C), one(0xF1BF), "IdBc"},
+{"fbun", one(0xF088), one(0xF1BF), "IdBc"},
+
+{"fcmpb", two(0xF000, 0x5838), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fcmpd", two(0xF000, 0x5438), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fcmpl", two(0xF000, 0x4038), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fcmpp", two(0xF000, 0x4C38), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fcmps", two(0xF000, 0x4438), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fcmpw", two(0xF000, 0x5038), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fcmpx", two(0xF000, 0x0038), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fcmpx", two(0xF000, 0x4838), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+/* {"fcmpx", two(0xF000, 0x0038), two(0xF1C0, 0xE07F), "IiFt"}, JF removed */
+
+{"fcosb", two(0xF000, 0x581D), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fcosd", two(0xF000, 0x541D), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fcosl", two(0xF000, 0x401D), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fcosp", two(0xF000, 0x4C1D), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fcoss", two(0xF000, 0x441D), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fcosw", two(0xF000, 0x501D), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fcosx", two(0xF000, 0x001D), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fcosx", two(0xF000, 0x481D), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fcosx", two(0xF000, 0x001D), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fcoshb", two(0xF000, 0x5819), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fcoshd", two(0xF000, 0x5419), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fcoshl", two(0xF000, 0x4019), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fcoshp", two(0xF000, 0x4C19), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fcoshs", two(0xF000, 0x4419), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fcoshw", two(0xF000, 0x5019), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fcoshx", two(0xF000, 0x0019), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fcoshx", two(0xF000, 0x4819), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fcoshx", two(0xF000, 0x0019), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fdbeq", two(0xF048, 0x0001), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbf", two(0xF048, 0x0000), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbge", two(0xF048, 0x0013), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbgl", two(0xF048, 0x0016), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbgle", two(0xF048, 0x0017), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbgt", two(0xF048, 0x0012), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdble", two(0xF048, 0x0015), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdblt", two(0xF048, 0x0014), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbne", two(0xF048, 0x000E), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbnge", two(0xF048, 0x001C), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbngl", two(0xF048, 0x0019), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbngle", two(0xF048, 0x0018), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbngt", two(0xF048, 0x001D), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbnle", two(0xF048, 0x001A), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbnlt", two(0xF048, 0x001B), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdboge", two(0xF048, 0x0003), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbogl", two(0xF048, 0x0006), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbogt", two(0xF048, 0x0002), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbole", two(0xF048, 0x0005), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbolt", two(0xF048, 0x0004), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbor", two(0xF048, 0x0007), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbseq", two(0xF048, 0x0011), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbsf", two(0xF048, 0x0010), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbsne", two(0xF048, 0x001E), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbst", two(0xF048, 0x001F), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbt", two(0xF048, 0x000F), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbueq", two(0xF048, 0x0009), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbuge", two(0xF048, 0x000B), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbugt", two(0xF048, 0x000A), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbule", two(0xF048, 0x000D), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbult", two(0xF048, 0x000C), two(0xF1F8, 0xFFFF), "IiDsBw"},
+{"fdbun", two(0xF048, 0x0008), two(0xF1F8, 0xFFFF), "IiDsBw"},
+
+{"fdivb", two(0xF000, 0x5820), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fdivd", two(0xF000, 0x5420), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fdivl", two(0xF000, 0x4020), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fdivp", two(0xF000, 0x4C20), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fdivs", two(0xF000, 0x4420), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fdivw", two(0xF000, 0x5020), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fdivx", two(0xF000, 0x0020), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fdivx", two(0xF000, 0x4820), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+/* {"fdivx", two(0xF000, 0x0020), two(0xF1C0, 0xE07F), "IiFt"}, JF */
+
+{"fetoxb", two(0xF000, 0x5810), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fetoxd", two(0xF000, 0x5410), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fetoxl", two(0xF000, 0x4010), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fetoxp", two(0xF000, 0x4C10), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fetoxs", two(0xF000, 0x4410), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fetoxw", two(0xF000, 0x5010), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fetoxx", two(0xF000, 0x0010), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fetoxx", two(0xF000, 0x4810), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fetoxx", two(0xF000, 0x0010), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fetoxm1b", two(0xF000, 0x5808), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fetoxm1d", two(0xF000, 0x5408), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fetoxm1l", two(0xF000, 0x4008), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fetoxm1p", two(0xF000, 0x4C08), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fetoxm1s", two(0xF000, 0x4408), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fetoxm1w", two(0xF000, 0x5008), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fetoxm1x", two(0xF000, 0x0008), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fetoxm1x", two(0xF000, 0x4808), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fetoxm1x", two(0xF000, 0x0008), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fgetexpb", two(0xF000, 0x581E), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fgetexpd", two(0xF000, 0x541E), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fgetexpl", two(0xF000, 0x401E), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fgetexpp", two(0xF000, 0x4C1E), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fgetexps", two(0xF000, 0x441E), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fgetexpw", two(0xF000, 0x501E), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fgetexpx", two(0xF000, 0x001E), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fgetexpx", two(0xF000, 0x481E), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fgetexpx", two(0xF000, 0x001E), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fgetmanb", two(0xF000, 0x581F), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fgetmand", two(0xF000, 0x541F), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fgetmanl", two(0xF000, 0x401F), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fgetmanp", two(0xF000, 0x4C1F), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fgetmans", two(0xF000, 0x441F), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fgetmanw", two(0xF000, 0x501F), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fgetmanx", two(0xF000, 0x001F), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fgetmanx", two(0xF000, 0x481F), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fgetmanx", two(0xF000, 0x001F), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fintb", two(0xF000, 0x5801), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fintd", two(0xF000, 0x5401), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fintl", two(0xF000, 0x4001), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fintp", two(0xF000, 0x4C01), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fints", two(0xF000, 0x4401), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fintw", two(0xF000, 0x5001), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fintx", two(0xF000, 0x0001), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fintx", two(0xF000, 0x4801), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fintx", two(0xF000, 0x0001), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fintrzb", two(0xF000, 0x5803), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fintrzd", two(0xF000, 0x5403), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fintrzl", two(0xF000, 0x4003), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fintrzp", two(0xF000, 0x4C03), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fintrzs", two(0xF000, 0x4403), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fintrzw", two(0xF000, 0x5003), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fintrzx", two(0xF000, 0x0003), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fintrzx", two(0xF000, 0x4803), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fintrzx", two(0xF000, 0x0003), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"flog10b", two(0xF000, 0x5815), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"flog10d", two(0xF000, 0x5415), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"flog10l", two(0xF000, 0x4015), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"flog10p", two(0xF000, 0x4C15), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"flog10s", two(0xF000, 0x4415), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"flog10w", two(0xF000, 0x5015), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"flog10x", two(0xF000, 0x0015), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"flog10x", two(0xF000, 0x4815), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"flog10x", two(0xF000, 0x0015), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"flog2b", two(0xF000, 0x5816), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"flog2d", two(0xF000, 0x5416), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"flog2l", two(0xF000, 0x4016), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"flog2p", two(0xF000, 0x4C16), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"flog2s", two(0xF000, 0x4416), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"flog2w", two(0xF000, 0x5016), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"flog2x", two(0xF000, 0x0016), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"flog2x", two(0xF000, 0x4816), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"flog2x", two(0xF000, 0x0016), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"flognb", two(0xF000, 0x5814), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"flognd", two(0xF000, 0x5414), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"flognl", two(0xF000, 0x4014), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"flognp", two(0xF000, 0x4C14), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"flogns", two(0xF000, 0x4414), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"flognw", two(0xF000, 0x5014), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"flognx", two(0xF000, 0x0014), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"flognx", two(0xF000, 0x4814), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"flognx", two(0xF000, 0x0014), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"flognp1b", two(0xF000, 0x5806), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"flognp1d", two(0xF000, 0x5406), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"flognp1l", two(0xF000, 0x4006), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"flognp1p", two(0xF000, 0x4C06), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"flognp1s", two(0xF000, 0x4406), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"flognp1w", two(0xF000, 0x5006), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"flognp1x", two(0xF000, 0x0006), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"flognp1x", two(0xF000, 0x4806), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"flognp1x", two(0xF000, 0x0006), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fmodb", two(0xF000, 0x5821), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fmodd", two(0xF000, 0x5421), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fmodl", two(0xF000, 0x4021), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fmodp", two(0xF000, 0x4C21), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fmods", two(0xF000, 0x4421), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fmodw", two(0xF000, 0x5021), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fmodx", two(0xF000, 0x0021), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fmodx", two(0xF000, 0x4821), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+/* {"fmodx", two(0xF000, 0x0021), two(0xF1C0, 0xE07F), "IiFt"}, JF */
+
+{"fmoveb", two(0xF000, 0x5800), two(0xF1C0, 0xFC7F), "Ii;bF7"}, /* fmove from <ea> to fp<n> */
+{"fmoveb", two(0xF000, 0x7800), two(0xF1C0, 0xFC7F), "IiF7@b"}, /* fmove from fp<n> to <ea> */
+{"fmoved", two(0xF000, 0x5400), two(0xF1C0, 0xFC7F), "Ii;FF7"}, /* fmove from <ea> to fp<n> */
+{"fmoved", two(0xF000, 0x7400), two(0xF1C0, 0xFC7F), "IiF7@F"}, /* fmove from fp<n> to <ea> */
+{"fmovel", two(0xF000, 0x4000), two(0xF1C0, 0xFC7F), "Ii;lF7"}, /* fmove from <ea> to fp<n> */
+{"fmovel", two(0xF000, 0x6000), two(0xF1C0, 0xFC7F), "IiF7@l"}, /* fmove from fp<n> to <ea> */
+/* Warning: The addressing modes on these are probably not right:
+ esp, Areg direct is only allowed for FPI */
+ /* fmove.l from/to system control registers: */
+{"fmovel", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "Iis8@s"},
+{"fmovel", two(0xF000, 0x8000), two(0xF1C0, 0xE3FF), "Ii*ls8"},
+
+/* {"fmovel", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "Iis8@s"},
+{"fmovel", two(0xF000, 0x8000), two(0xF2C0, 0xE3FF), "Ii*ss8"}, */
+
+{"fmovep", two(0xF000, 0x4C00), two(0xF1C0, 0xFC7F), "Ii;pF7"}, /* fmove from <ea> to fp<n> */
+{"fmovep", two(0xF000, 0x6C00), two(0xF1C0, 0xFC00), "IiF7@pkC"}, /* fmove.p with k-factors: */
+{"fmovep", two(0xF000, 0x7C00), two(0xF1C0, 0xFC0F), "IiF7@pDk"}, /* fmove.p with k-factors: */
+
+{"fmoves", two(0xF000, 0x4400), two(0xF1C0, 0xFC7F), "Ii;fF7"}, /* fmove from <ea> to fp<n> */
+{"fmoves", two(0xF000, 0x6400), two(0xF1C0, 0xFC7F), "IiF7@f"}, /* fmove from fp<n> to <ea> */
+{"fmovew", two(0xF000, 0x5000), two(0xF1C0, 0xFC7F), "Ii;wF7"}, /* fmove from <ea> to fp<n> */
+{"fmovew", two(0xF000, 0x7000), two(0xF1C0, 0xFC7F), "IiF7@w"}, /* fmove from fp<n> to <ea> */
+{"fmovex", two(0xF000, 0x0000), two(0xF1C0, 0xE07F), "IiF8F7"}, /* fmove from <ea> to fp<n> */
+{"fmovex", two(0xF000, 0x4800), two(0xF1C0, 0xFC7F), "Ii;xF7"}, /* fmove from <ea> to fp<n> */
+{"fmovex", two(0xF000, 0x6800), two(0xF1C0, 0xFC7F), "IiF7@x"}, /* fmove from fp<n> to <ea> */
+/* JF removed {"fmovex", two(0xF000, 0x0000), two(0xF1C0, 0xE07F), "IiFt"}, / * fmove from <ea> to fp<n> */
+
+{"fmovecrx", two(0xF000, 0x5C00), two(0xF1FF, 0xFC00), "Ii#CF7"}, /* fmovecr.x #ccc, FPn */
+{"fmovecr", two(0xF000, 0x5C00), two(0xF1FF, 0xFC00), "Ii#CF7"},
+
+/* Other fmovemx. */
+{"fmovemx", two(0xF020, 0xE000), two(0xF1F8, 0xFF00), "IdL3-s"}, /* fmovem.x to autodecrement, static and dynamic */
+{"fmovemx", two(0xF020, 0xE000), two(0xF1F8, 0xFF00), "Id#3-s"}, /* fmovem.x to autodecrement, static and dynamic */
+
+{"fmovemx", two(0xF020, 0xE800), two(0xF1F8, 0xFF8F), "IiDk-s"}, /* fmovem.x to autodecrement, static and dynamic */
+
+{"fmovemx", two(0xF000, 0xF000), two(0xF1C0, 0xFF00), "Id#3&s"}, /* fmovem.x to control, static and dynamic: */
+{"fmovemx", two(0xF000, 0xF800), two(0xF1C0, 0xFF8F), "IiDk&s"}, /* fmovem.x to control, static and dynamic: */
+{"fmovemx", two(0xF000, 0xD000), two(0xF1C0, 0xFF00), "Id&s#3"}, /* fmovem.x from control, static and dynamic: */
+{"fmovemx", two(0xF000, 0xD800), two(0xF1C0, 0xFF8F), "Ii&sDk"}, /* fmovem.x from control, static and dynamic: */
+{"fmovemx", two(0xF000, 0xF000), two(0xF1C0, 0xFF00), "Idl3&s"}, /* fmovem.x to control, static and dynamic: */
+{"fmovemx", two(0xF000, 0xD000), two(0xF1C0, 0xFF00), "Id&sl3"}, /* fmovem.x from control, static and dynamic: */
+
+{"fmovemx", two(0xF018, 0xD000), two(0xF1F8, 0xFF00), "Id+sl3"}, /* fmovem.x from autoincrement, static and dynamic: */
+{"fmovemx", two(0xF018, 0xD000), two(0xF1F8, 0xFF00), "Id+s#3"}, /* fmovem.x from autoincrement, static and dynamic: */
+{"fmovemx", two(0xF018, 0xD800), two(0xF1F8, 0xFF8F), "Ii+sDk"}, /* fmovem.x from autoincrement, static and dynamic: */
+
+{"fmoveml", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "IiL8@s"},
+{"fmoveml", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "Ii#8@s"},
+{"fmoveml", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "Iis8@s"},
+
+{"fmoveml", two(0xF000, 0x8000), two(0xF2C0, 0xE3FF), "Ii*sL8"},
+{"fmoveml", two(0xF000, 0x8000), two(0xF1C0, 0xE3FF), "Ii*s#8"},
+{"fmoveml", two(0xF000, 0x8000), two(0xF1C0, 0xE3FF), "Ii*ss8"},
+
+/* fmovemx with register lists */
+{"fmovem", two(0xF020, 0xE000), two(0xF1F8, 0xFF00), "IdL3-s"}, /* fmovem.x to autodecrement, static and dynamic */
+{"fmovem", two(0xF000, 0xF000), two(0xF1C0, 0xFF00), "Idl3&s"}, /* fmovem.x to control, static and dynamic: */
+{"fmovem", two(0xF018, 0xD000), two(0xF1F8, 0xFF00), "Id+sl3"}, /* fmovem.x from autoincrement, static and dynamic: */
+{"fmovem", two(0xF000, 0xD000), two(0xF1C0, 0xFF00), "Id&sl3"}, /* fmovem.x from control, static and dynamic: */
+
+ /* Alternate mnemonics for GNU as and GNU CC */
+{"fmovem", two(0xF020, 0xE000), two(0xF1F8, 0xFF00), "Id#3-s"}, /* fmovem.x to autodecrement, static and dynamic */
+{"fmovem", two(0xF020, 0xE800), two(0xF1F8, 0xFF8F), "IiDk-s"}, /* fmovem.x to autodecrement, static and dynamic */
+
+{"fmovem", two(0xF000, 0xF000), two(0xF1C0, 0xFF00), "Id#3&s"}, /* fmovem.x to control, static and dynamic: */
+{"fmovem", two(0xF000, 0xF800), two(0xF1C0, 0xFF8F), "IiDk&s"}, /* fmovem.x to control, static and dynamic: */
+
+{"fmovem", two(0xF018, 0xD000), two(0xF1F8, 0xFF00), "Id+s#3"}, /* fmovem.x from autoincrement, static and dynamic: */
+{"fmovem", two(0xF018, 0xD800), two(0xF1F8, 0xFF8F), "Ii+sDk"}, /* fmovem.x from autoincrement, static and dynamic: */
+
+{"fmovem", two(0xF000, 0xD000), two(0xF1C0, 0xFF00), "Id&s#3"}, /* fmovem.x from control, static and dynamic: */
+{"fmovem", two(0xF000, 0xD800), two(0xF1C0, 0xFF8F), "Ii&sDk"}, /* fmovem.x from control, static and dynamic: */
+
+/* fmoveml a FP-control register */
+{"fmovem", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "Iis8@s"},
+{"fmovem", two(0xF000, 0x8000), two(0xF1C0, 0xE3FF), "Ii*ss8"},
+
+/* fmoveml a FP-control reglist */
+{"fmovem", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "IiL8@s"},
+{"fmovem", two(0xF000, 0x8000), two(0xF2C0, 0xE3FF), "Ii*sL8"},
+
+{"fmulb", two(0xF000, 0x5823), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fmuld", two(0xF000, 0x5423), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fmull", two(0xF000, 0x4023), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fmulp", two(0xF000, 0x4C23), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fmuls", two(0xF000, 0x4423), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fmulw", two(0xF000, 0x5023), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fmulx", two(0xF000, 0x0023), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fmulx", two(0xF000, 0x4823), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+/* {"fmulx", two(0xF000, 0x0023), two(0xF1C0, 0xE07F), "IiFt"}, JF */
+
+{"fnegb", two(0xF000, 0x581A), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fnegd", two(0xF000, 0x541A), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fnegl", two(0xF000, 0x401A), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fnegp", two(0xF000, 0x4C1A), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fnegs", two(0xF000, 0x441A), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fnegw", two(0xF000, 0x501A), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fnegx", two(0xF000, 0x001A), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fnegx", two(0xF000, 0x481A), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fnegx", two(0xF000, 0x001A), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fnop", two(0xF280, 0x0000), two(0xFFFF, 0xFFFF), "Ii"},
+
+{"fremb", two(0xF000, 0x5825), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fremd", two(0xF000, 0x5425), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"freml", two(0xF000, 0x4025), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fremp", two(0xF000, 0x4C25), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"frems", two(0xF000, 0x4425), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fremw", two(0xF000, 0x5025), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fremx", two(0xF000, 0x0025), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fremx", two(0xF000, 0x4825), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+/* {"fremx", two(0xF000, 0x0025), two(0xF1C0, 0xE07F), "IiFt"}, JF */
+
+{"frestore", one(0xF140), one(0xF1C0), "Id&s"},
+{"frestore", one(0xF158), one(0xF1F8), "Id+s"},
+{"fsave", one(0xF100), one(0xF1C0), "Id&s"},
+{"fsave", one(0xF120), one(0xF1F8), "Id-s"},
+
+{"fsincosb", two(0xF000, 0x5830), two(0xF1C0, 0xFC78), "Ii;bF3F7"},
+{"fsincosd", two(0xF000, 0x5430), two(0xF1C0, 0xFC78), "Ii;FF3F7"},
+{"fsincosl", two(0xF000, 0x4030), two(0xF1C0, 0xFC78), "Ii;lF3F7"},
+{"fsincosp", two(0xF000, 0x4C30), two(0xF1C0, 0xFC78), "Ii;pF3F7"},
+{"fsincoss", two(0xF000, 0x4430), two(0xF1C0, 0xFC78), "Ii;fF3F7"},
+{"fsincosw", two(0xF000, 0x5030), two(0xF1C0, 0xFC78), "Ii;wF3F7"},
+{"fsincosx", two(0xF000, 0x0030), two(0xF1C0, 0xE078), "IiF8F3F7"},
+{"fsincosx", two(0xF000, 0x4830), two(0xF1C0, 0xFC78), "Ii;xF3F7"},
+
+{"fscaleb", two(0xF000, 0x5826), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fscaled", two(0xF000, 0x5426), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fscalel", two(0xF000, 0x4026), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fscalep", two(0xF000, 0x4C26), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fscales", two(0xF000, 0x4426), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fscalew", two(0xF000, 0x5026), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fscalex", two(0xF000, 0x0026), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fscalex", two(0xF000, 0x4826), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+/* {"fscalex", two(0xF000, 0x0026), two(0xF1C0, 0xE07F), "IiFt"}, JF */
+
+/* $ is necessary to prevent the assembler from using PC-relative.
+ If @ were used, "label: fseq label" could produce "ftrapeq",
+ because "label" became "pc@label". */
+{"fseq", two(0xF040, 0x0001), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsf", two(0xF040, 0x0000), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsge", two(0xF040, 0x0013), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsgl", two(0xF040, 0x0016), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsgle", two(0xF040, 0x0017), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsgt", two(0xF040, 0x0012), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsle", two(0xF040, 0x0015), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fslt", two(0xF040, 0x0014), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsne", two(0xF040, 0x000E), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsnge", two(0xF040, 0x001C), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsngl", two(0xF040, 0x0019), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsngle", two(0xF040, 0x0018), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsngt", two(0xF040, 0x001D), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsnle", two(0xF040, 0x001A), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsnlt", two(0xF040, 0x001B), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsoge", two(0xF040, 0x0003), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsogl", two(0xF040, 0x0006), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsogt", two(0xF040, 0x0002), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsole", two(0xF040, 0x0005), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsolt", two(0xF040, 0x0004), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsor", two(0xF040, 0x0007), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsseq", two(0xF040, 0x0011), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fssf", two(0xF040, 0x0010), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fssne", two(0xF040, 0x001E), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsst", two(0xF040, 0x001F), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fst", two(0xF040, 0x000F), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsueq", two(0xF040, 0x0009), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsuge", two(0xF040, 0x000B), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsugt", two(0xF040, 0x000A), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsule", two(0xF040, 0x000D), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsult", two(0xF040, 0x000C), two(0xF1C0, 0xFFFF), "Ii$s"},
+{"fsun", two(0xF040, 0x0008), two(0xF1C0, 0xFFFF), "Ii$s"},
+
+{"fsgldivb", two(0xF000, 0x5824), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fsgldivd", two(0xF000, 0x5424), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fsgldivl", two(0xF000, 0x4024), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fsgldivp", two(0xF000, 0x4C24), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fsgldivs", two(0xF000, 0x4424), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fsgldivw", two(0xF000, 0x5024), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fsgldivx", two(0xF000, 0x0024), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fsgldivx", two(0xF000, 0x4824), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fsgldivx", two(0xF000, 0x0024), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fsglmulb", two(0xF000, 0x5827), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fsglmuld", two(0xF000, 0x5427), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fsglmull", two(0xF000, 0x4027), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fsglmulp", two(0xF000, 0x4C27), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fsglmuls", two(0xF000, 0x4427), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fsglmulw", two(0xF000, 0x5027), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fsglmulx", two(0xF000, 0x0027), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fsglmulx", two(0xF000, 0x4827), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fsglmulx", two(0xF000, 0x0027), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fsinb", two(0xF000, 0x580E), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fsind", two(0xF000, 0x540E), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fsinl", two(0xF000, 0x400E), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fsinp", two(0xF000, 0x4C0E), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fsins", two(0xF000, 0x440E), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fsinw", two(0xF000, 0x500E), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fsinx", two(0xF000, 0x000E), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fsinx", two(0xF000, 0x480E), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fsinx", two(0xF000, 0x000E), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fsinhb", two(0xF000, 0x5802), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fsinhd", two(0xF000, 0x5402), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fsinhl", two(0xF000, 0x4002), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fsinhp", two(0xF000, 0x4C02), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fsinhs", two(0xF000, 0x4402), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fsinhw", two(0xF000, 0x5002), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fsinhx", two(0xF000, 0x0002), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fsinhx", two(0xF000, 0x4802), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fsinhx", two(0xF000, 0x0002), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fsqrtb", two(0xF000, 0x5804), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fsqrtd", two(0xF000, 0x5404), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fsqrtl", two(0xF000, 0x4004), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fsqrtp", two(0xF000, 0x4C04), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fsqrts", two(0xF000, 0x4404), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fsqrtw", two(0xF000, 0x5004), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fsqrtx", two(0xF000, 0x0004), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fsqrtx", two(0xF000, 0x4804), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fsqrtx", two(0xF000, 0x0004), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"fsubb", two(0xF000, 0x5828), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"fsubd", two(0xF000, 0x5428), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"fsubl", two(0xF000, 0x4028), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"fsubp", two(0xF000, 0x4C28), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"fsubs", two(0xF000, 0x4428), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"fsubw", two(0xF000, 0x5028), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"fsubx", two(0xF000, 0x0028), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"fsubx", two(0xF000, 0x4828), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"fsubx", two(0xF000, 0x0028), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"ftanb", two(0xF000, 0x580F), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"ftand", two(0xF000, 0x540F), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"ftanl", two(0xF000, 0x400F), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"ftanp", two(0xF000, 0x4C0F), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"ftans", two(0xF000, 0x440F), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"ftanw", two(0xF000, 0x500F), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"ftanx", two(0xF000, 0x000F), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"ftanx", two(0xF000, 0x480F), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"ftanx", two(0xF000, 0x000F), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"ftanhb", two(0xF000, 0x5809), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"ftanhd", two(0xF000, 0x5409), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"ftanhl", two(0xF000, 0x4009), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"ftanhp", two(0xF000, 0x4C09), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"ftanhs", two(0xF000, 0x4409), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"ftanhw", two(0xF000, 0x5009), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"ftanhx", two(0xF000, 0x0009), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"ftanhx", two(0xF000, 0x4809), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"ftanhx", two(0xF000, 0x0009), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"ftentoxb", two(0xF000, 0x5812), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"ftentoxd", two(0xF000, 0x5412), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"ftentoxl", two(0xF000, 0x4012), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"ftentoxp", two(0xF000, 0x4C12), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"ftentoxs", two(0xF000, 0x4412), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"ftentoxw", two(0xF000, 0x5012), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"ftentoxx", two(0xF000, 0x0012), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"ftentoxx", two(0xF000, 0x4812), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"ftentoxx", two(0xF000, 0x0012), two(0xF1C0, 0xE07F), "IiFt"},
+
+{"ftrapeq", two(0xF07C, 0x0001), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapf", two(0xF07C, 0x0000), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapge", two(0xF07C, 0x0013), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapgl", two(0xF07C, 0x0016), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapgle", two(0xF07C, 0x0017), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapgt", two(0xF07C, 0x0012), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftraple", two(0xF07C, 0x0015), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftraplt", two(0xF07C, 0x0014), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapne", two(0xF07C, 0x000E), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapnge", two(0xF07C, 0x001C), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapngl", two(0xF07C, 0x0019), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapngle", two(0xF07C, 0x0018), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapngt", two(0xF07C, 0x001D), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapnle", two(0xF07C, 0x001A), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapnlt", two(0xF07C, 0x001B), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapoge", two(0xF07C, 0x0003), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapogl", two(0xF07C, 0x0006), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapogt", two(0xF07C, 0x0002), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapole", two(0xF07C, 0x0005), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapolt", two(0xF07C, 0x0004), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapor", two(0xF07C, 0x0007), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapseq", two(0xF07C, 0x0011), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapsf", two(0xF07C, 0x0010), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapsne", two(0xF07C, 0x001E), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapst", two(0xF07C, 0x001F), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapt", two(0xF07C, 0x000F), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapueq", two(0xF07C, 0x0009), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapuge", two(0xF07C, 0x000B), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapugt", two(0xF07C, 0x000A), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapule", two(0xF07C, 0x000D), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapult", two(0xF07C, 0x000C), two(0xF1FF, 0xFFFF), "Ii"},
+{"ftrapun", two(0xF07C, 0x0008), two(0xF1FF, 0xFFFF), "Ii"},
+
+{"ftrapeqw", two(0xF07A, 0x0001), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapfw", two(0xF07A, 0x0000), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapgew", two(0xF07A, 0x0013), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapglw", two(0xF07A, 0x0016), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapglew", two(0xF07A, 0x0017), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapgtw", two(0xF07A, 0x0012), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftraplew", two(0xF07A, 0x0015), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapltw", two(0xF07A, 0x0014), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapnew", two(0xF07A, 0x000E), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapngew", two(0xF07A, 0x001C), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapnglw", two(0xF07A, 0x0019), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapnglew", two(0xF07A, 0x0018), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapngtw", two(0xF07A, 0x001D), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapnlew", two(0xF07A, 0x001A), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapnltw", two(0xF07A, 0x001B), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapogew", two(0xF07A, 0x0003), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapoglw", two(0xF07A, 0x0006), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapogtw", two(0xF07A, 0x0002), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapolew", two(0xF07A, 0x0005), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapoltw", two(0xF07A, 0x0004), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftraporw", two(0xF07A, 0x0007), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapseqw", two(0xF07A, 0x0011), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapsfw", two(0xF07A, 0x0010), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapsnew", two(0xF07A, 0x001E), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapstw", two(0xF07A, 0x001F), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftraptw", two(0xF07A, 0x000F), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapueqw", two(0xF07A, 0x0009), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapugew", two(0xF07A, 0x000B), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapugtw", two(0xF07A, 0x000A), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapulew", two(0xF07A, 0x000D), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapultw", two(0xF07A, 0x000C), two(0xF1FF, 0xFFFF), "Ii^w"},
+{"ftrapunw", two(0xF07A, 0x0008), two(0xF1FF, 0xFFFF), "Ii^w"},
+
+{"ftrapeql", two(0xF07B, 0x0001), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapfl", two(0xF07B, 0x0000), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapgel", two(0xF07B, 0x0013), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapgll", two(0xF07B, 0x0016), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapglel", two(0xF07B, 0x0017), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapgtl", two(0xF07B, 0x0012), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftraplel", two(0xF07B, 0x0015), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapltl", two(0xF07B, 0x0014), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapnel", two(0xF07B, 0x000E), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapngel", two(0xF07B, 0x001C), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapngll", two(0xF07B, 0x0019), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapnglel", two(0xF07B, 0x0018), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapngtl", two(0xF07B, 0x001D), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapnlel", two(0xF07B, 0x001A), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapnltl", two(0xF07B, 0x001B), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapogel", two(0xF07B, 0x0003), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapogll", two(0xF07B, 0x0006), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapogtl", two(0xF07B, 0x0002), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapolel", two(0xF07B, 0x0005), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapoltl", two(0xF07B, 0x0004), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftraporl", two(0xF07B, 0x0007), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapseql", two(0xF07B, 0x0011), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapsfl", two(0xF07B, 0x0010), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapsnel", two(0xF07B, 0x001E), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapstl", two(0xF07B, 0x001F), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftraptl", two(0xF07B, 0x000F), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapueql", two(0xF07B, 0x0009), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapugel", two(0xF07B, 0x000B), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapugtl", two(0xF07B, 0x000A), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapulel", two(0xF07B, 0x000D), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapultl", two(0xF07B, 0x000C), two(0xF1FF, 0xFFFF), "Ii^l"},
+{"ftrapunl", two(0xF07B, 0x0008), two(0xF1FF, 0xFFFF), "Ii^l"},
+
+{"ftstb", two(0xF000, 0x583A), two(0xF1C0, 0xFC7F), "Ii;b"},
+{"ftstd", two(0xF000, 0x543A), two(0xF1C0, 0xFC7F), "Ii;F"},
+{"ftstl", two(0xF000, 0x403A), two(0xF1C0, 0xFC7F), "Ii;l"},
+{"ftstp", two(0xF000, 0x4C3A), two(0xF1C0, 0xFC7F), "Ii;p"},
+{"ftsts", two(0xF000, 0x443A), two(0xF1C0, 0xFC7F), "Ii;f"},
+{"ftstw", two(0xF000, 0x503A), two(0xF1C0, 0xFC7F), "Ii;w"},
+{"ftstx", two(0xF000, 0x003A), two(0xF1C0, 0xE07F), "IiF8"},
+{"ftstx", two(0xF000, 0x483A), two(0xF1C0, 0xFC7F), "Ii;x"},
+
+{"ftwotoxb", two(0xF000, 0x5811), two(0xF1C0, 0xFC7F), "Ii;bF7"},
+{"ftwotoxd", two(0xF000, 0x5411), two(0xF1C0, 0xFC7F), "Ii;FF7"},
+{"ftwotoxl", two(0xF000, 0x4011), two(0xF1C0, 0xFC7F), "Ii;lF7"},
+{"ftwotoxp", two(0xF000, 0x4C11), two(0xF1C0, 0xFC7F), "Ii;pF7"},
+{"ftwotoxs", two(0xF000, 0x4411), two(0xF1C0, 0xFC7F), "Ii;fF7"},
+{"ftwotoxw", two(0xF000, 0x5011), two(0xF1C0, 0xFC7F), "Ii;wF7"},
+{"ftwotoxx", two(0xF000, 0x0011), two(0xF1C0, 0xE07F), "IiF8F7"},
+{"ftwotoxx", two(0xF000, 0x4811), two(0xF1C0, 0xFC7F), "Ii;xF7"},
+{"ftwotoxx", two(0xF000, 0x0011), two(0xF1C0, 0xE07F), "IiFt"},
+
+
+{"fjeq", one(0xF081), one(0xF1FF), "IdBc"},
+{"fjf", one(0xF080), one(0xF1FF), "IdBc"},
+{"fjge", one(0xF093), one(0xF1FF), "IdBc"},
+{"fjgl", one(0xF096), one(0xF1FF), "IdBc"},
+{"fjgle", one(0xF097), one(0xF1FF), "IdBc"},
+{"fjgt", one(0xF092), one(0xF1FF), "IdBc"},
+{"fjle", one(0xF095), one(0xF1FF), "IdBc"},
+{"fjlt", one(0xF094), one(0xF1FF), "IdBc"},
+{"fjne", one(0xF08E), one(0xF1FF), "IdBc"},
+{"fjnge", one(0xF09C), one(0xF1FF), "IdBc"},
+{"fjngl", one(0xF099), one(0xF1FF), "IdBc"},
+{"fjngle", one(0xF098), one(0xF1FF), "IdBc"},
+{"fjngt", one(0xF09D), one(0xF1FF), "IdBc"},
+{"fjnle", one(0xF09A), one(0xF1FF), "IdBc"},
+{"fjnlt", one(0xF09B), one(0xF1FF), "IdBc"},
+{"fjoge", one(0xF083), one(0xF1FF), "IdBc"},
+{"fjogl", one(0xF086), one(0xF1FF), "IdBc"},
+{"fjogt", one(0xF082), one(0xF1FF), "IdBc"},
+{"fjole", one(0xF085), one(0xF1FF), "IdBc"},
+{"fjolt", one(0xF084), one(0xF1FF), "IdBc"},
+{"fjor", one(0xF087), one(0xF1FF), "IdBc"},
+{"fjseq", one(0xF091), one(0xF1FF), "IdBc"},
+{"fjsf", one(0xF090), one(0xF1FF), "IdBc"},
+{"fjsne", one(0xF09E), one(0xF1FF), "IdBc"},
+{"fjst", one(0xF09F), one(0xF1FF), "IdBc"},
+{"fjt", one(0xF08F), one(0xF1FF), "IdBc"},
+{"fjueq", one(0xF089), one(0xF1FF), "IdBc"},
+{"fjuge", one(0xF08B), one(0xF1FF), "IdBc"},
+{"fjugt", one(0xF08A), one(0xF1FF), "IdBc"},
+{"fjule", one(0xF08D), one(0xF1FF), "IdBc"},
+{"fjult", one(0xF08C), one(0xF1FF), "IdBc"},
+{"fjun", one(0xF088), one(0xF1FF), "IdBc"},
+
+/* The assembler will ignore attempts to force a short offset */
+
+{"bhis", one(0061000), one(0177400), "Bg"},
+{"blss", one(0061400), one(0177400), "Bg"},
+{"bccs", one(0062000), one(0177400), "Bg"},
+{"bcss", one(0062400), one(0177400), "Bg"},
+{"bnes", one(0063000), one(0177400), "Bg"},
+{"beqs", one(0063400), one(0177400), "Bg"},
+{"bvcs", one(0064000), one(0177400), "Bg"},
+{"bvss", one(0064400), one(0177400), "Bg"},
+{"bpls", one(0065000), one(0177400), "Bg"},
+{"bmis", one(0065400), one(0177400), "Bg"},
+{"bges", one(0066000), one(0177400), "Bg"},
+{"blts", one(0066400), one(0177400), "Bg"},
+{"bgts", one(0067000), one(0177400), "Bg"},
+{"bles", one(0067400), one(0177400), "Bg"},
+
+/* Alternate mnemonics for SUN */
+
+{"jbsr", one(0060400), one(0177400), "Bg"},
+{"jbsr", one(0047200), one(0177700), "!s"},
+{"jra", one(0060000), one(0177400), "Bg"},
+{"jra", one(0047300), one(0177700), "!s"},
+
+{"jhi", one(0061000), one(0177400), "Bg"},
+{"jls", one(0061400), one(0177400), "Bg"},
+{"jcc", one(0062000), one(0177400), "Bg"},
+{"jcs", one(0062400), one(0177400), "Bg"},
+{"jne", one(0063000), one(0177400), "Bg"},
+{"jeq", one(0063400), one(0177400), "Bg"},
+{"jvc", one(0064000), one(0177400), "Bg"},
+{"jvs", one(0064400), one(0177400), "Bg"},
+{"jpl", one(0065000), one(0177400), "Bg"},
+{"jmi", one(0065400), one(0177400), "Bg"},
+{"jge", one(0066000), one(0177400), "Bg"},
+{"jlt", one(0066400), one(0177400), "Bg"},
+{"jgt", one(0067000), one(0177400), "Bg"},
+{"jle", one(0067400), one(0177400), "Bg"},
+
+/* Short offsets are ignored */
+
+{"jbsrs", one(0060400), one(0177400), "Bg"},
+{"jras", one(0060000), one(0177400), "Bg"},
+{"jhis", one(0061000), one(0177400), "Bg"},
+{"jlss", one(0061400), one(0177400), "Bg"},
+{"jccs", one(0062000), one(0177400), "Bg"},
+{"jcss", one(0062400), one(0177400), "Bg"},
+{"jnes", one(0063000), one(0177400), "Bg"},
+{"jeqs", one(0063400), one(0177400), "Bg"},
+{"jvcs", one(0064000), one(0177400), "Bg"},
+{"jvss", one(0064400), one(0177400), "Bg"},
+{"jpls", one(0065000), one(0177400), "Bg"},
+{"jmis", one(0065400), one(0177400), "Bg"},
+{"jges", one(0066000), one(0177400), "Bg"},
+{"jlts", one(0066400), one(0177400), "Bg"},
+{"jgts", one(0067000), one(0177400), "Bg"},
+{"jles", one(0067400), one(0177400), "Bg"},
+
+{"movql", one(0070000), one(0170400), "MsDd"},
+{"moveql", one(0070000), one(0170400), "MsDd"},
+{"moval", one(0020100), one(0170700), "*lAd"},
+{"movaw", one(0030100), one(0170700), "*wAd"},
+{"movb", one(0010000), one(0170000), ";b$d"}, /* mov */
+{"movl", one(0070000), one(0170400), "MsDd"}, /* movq written as mov */
+{"movl", one(0020000), one(0170000), "*l$d"},
+{"movl", one(0020100), one(0170700), "*lAd"},
+{"movl", one(0047140), one(0177770), "AsUd"}, /* mov to USP */
+{"movl", one(0047150), one(0177770), "UdAs"}, /* mov from USP */
+{"movc", one(0047173), one(0177777), "R1Jj"},
+{"movc", one(0047173), one(0177777), "R1#j"},
+{"movc", one(0047172), one(0177777), "JjR1"},
+{"movc", one(0047172), one(0177777), "#jR1"},
+{"movml", one(0044300), one(0177700), "#w&s"}, /* movm reg to mem. */
+{"movml", one(0044340), one(0177770), "#w-s"}, /* movm reg to autodecrement. */
+{"movml", one(0046300), one(0177700), "!s#w"}, /* movm mem to reg. */
+{"movml", one(0046330), one(0177770), "+s#w"}, /* movm autoinc to reg. */
+{"movml", one(0044300), one(0177700), "Lw&s"}, /* movm reg to mem. */
+{"movml", one(0044340), one(0177770), "lw-s"}, /* movm reg to autodecrement. */
+{"movml", one(0046300), one(0177700), "!sLw"}, /* movm mem to reg. */
+{"movml", one(0046330), one(0177770), "+sLw"}, /* movm autoinc to reg. */
+{"movmw", one(0044200), one(0177700), "#w&s"}, /* movm reg to mem. */
+{"movmw", one(0044240), one(0177770), "#w-s"}, /* movm reg to autodecrement. */
+{"movmw", one(0046200), one(0177700), "!s#w"}, /* movm mem to reg. */
+{"movmw", one(0046230), one(0177770), "+s#w"}, /* movm autoinc to reg. */
+{"movmw", one(0044200), one(0177700), "Lw&s"}, /* movm reg to mem. */
+{"movmw", one(0044240), one(0177770), "lw-s"}, /* movm reg to autodecrement. */
+{"movmw", one(0046200), one(0177700), "!sLw"}, /* movm mem to reg. */
+{"movmw", one(0046230), one(0177770), "+sLw"}, /* movm autoinc to reg. */
+{"movpl", one(0000510), one(0170770), "dsDd"}, /* memory to register */
+{"movpl", one(0000710), one(0170770), "Ddds"}, /* register to memory */
+{"movpw", one(0000410), one(0170770), "dsDd"}, /* memory to register */
+{"movpw", one(0000610), one(0170770), "Ddds"}, /* register to memory */
+{"movq", one(0070000), one(0170400), "MsDd"},
+{"movw", one(0030000), one(0170000), "*w$d"},
+{"movw", one(0030100), one(0170700), "*wAd"}, /* mova, written as mov */
+{"movw", one(0040300), one(0177700), "Ss$s"}, /* Move from sr */
+{"movw", one(0041300), one(0177700), "Cs$s"}, /* Move from ccr */
+{"movw", one(0042300), one(0177700), ";wCd"}, /* mov to ccr */
+{"movw", one(0043300), one(0177700), ";wSd"}, /* mov to sr */
+
+{"movsb", two(0007000, 0), two(0177700, 07777), "~sR1"},
+{"movsb", two(0007000, 04000), two(0177700, 07777), "R1~s"},
+{"movsl", two(0007200, 0), two(0177700, 07777), "~sR1"},
+{"movsl", two(0007200, 04000), two(0177700, 07777), "R1~s"},
+{"movsw", two(0007100, 0), two(0177700, 07777), "~sR1"},
+{"movsw", two(0007100, 04000), two(0177700, 07777), "R1~s"},
+
+#ifdef m68851
+ /* name */ /* opcode */ /* match */ /* args */
+
+{"pbac", one(0xf0c7), one(0xffbf), "Bc"},
+{"pbacw", one(0xf087), one(0xffbf), "Bc"},
+{"pbas", one(0xf0c6), one(0xffbf), "Bc"},
+{"pbasw", one(0xf086), one(0xffbf), "Bc"},
+{"pbbc", one(0xf0c1), one(0xffbf), "Bc"},
+{"pbbcw", one(0xf081), one(0xffbf), "Bc"},
+{"pbbs", one(0xf0c0), one(0xffbf), "Bc"},
+{"pbbsw", one(0xf080), one(0xffbf), "Bc"},
+{"pbcc", one(0xf0cf), one(0xffbf), "Bc"},
+{"pbccw", one(0xf08f), one(0xffbf), "Bc"},
+{"pbcs", one(0xf0ce), one(0xffbf), "Bc"},
+{"pbcsw", one(0xf08e), one(0xffbf), "Bc"},
+{"pbgc", one(0xf0cd), one(0xffbf), "Bc"},
+{"pbgcw", one(0xf08d), one(0xffbf), "Bc"},
+{"pbgs", one(0xf0cc), one(0xffbf), "Bc"},
+{"pbgsw", one(0xf08c), one(0xffbf), "Bc"},
+{"pbic", one(0xf0cb), one(0xffbf), "Bc"},
+{"pbicw", one(0xf08b), one(0xffbf), "Bc"},
+{"pbis", one(0xf0ca), one(0xffbf), "Bc"},
+{"pbisw", one(0xf08a), one(0xffbf), "Bc"},
+{"pblc", one(0xf0c3), one(0xffbf), "Bc"},
+{"pblcw", one(0xf083), one(0xffbf), "Bc"},
+{"pbls", one(0xf0c2), one(0xffbf), "Bc"},
+{"pblsw", one(0xf082), one(0xffbf), "Bc"},
+{"pbsc", one(0xf0c5), one(0xffbf), "Bc"},
+{"pbscw", one(0xf085), one(0xffbf), "Bc"},
+{"pbss", one(0xf0c4), one(0xffbf), "Bc"},
+{"pbssw", one(0xf084), one(0xffbf), "Bc"},
+{"pbwc", one(0xf0c9), one(0xffbf), "Bc"},
+{"pbwcw", one(0xf089), one(0xffbf), "Bc"},
+{"pbws", one(0xf0c8), one(0xffbf), "Bc"},
+{"pbwsw", one(0xf088), one(0xffbf), "Bc"},
+
+
+{"pdbac", two(0xf048, 0x0007), two(0xfff8, 0xffff), "DsBw"},
+{"pdbas", two(0xf048, 0x0006), two(0xfff8, 0xffff), "DsBw"},
+{"pdbbc", two(0xf048, 0x0001), two(0xfff8, 0xffff), "DsBw"},
+{"pdbbs", two(0xf048, 0x0000), two(0xfff8, 0xffff), "DsBw"},
+{"pdbcc", two(0xf048, 0x000f), two(0xfff8, 0xffff), "DsBw"},
+{"pdbcs", two(0xf048, 0x000e), two(0xfff8, 0xffff), "DsBw"},
+{"pdbgc", two(0xf048, 0x000d), two(0xfff8, 0xffff), "DsBw"},
+{"pdbgs", two(0xf048, 0x000c), two(0xfff8, 0xffff), "DsBw"},
+{"pdbic", two(0xf048, 0x000b), two(0xfff8, 0xffff), "DsBw"},
+{"pdbis", two(0xf048, 0x000a), two(0xfff8, 0xffff), "DsBw"},
+{"pdblc", two(0xf048, 0x0003), two(0xfff8, 0xffff), "DsBw"},
+{"pdbls", two(0xf048, 0x0002), two(0xfff8, 0xffff), "DsBw"},
+{"pdbsc", two(0xf048, 0x0005), two(0xfff8, 0xffff), "DsBw"},
+{"pdbss", two(0xf048, 0x0004), two(0xfff8, 0xffff), "DsBw"},
+{"pdbwc", two(0xf048, 0x0009), two(0xfff8, 0xffff), "DsBw"},
+{"pdbws", two(0xf048, 0x0008), two(0xfff8, 0xffff), "DsBw"},
+
+{"pflusha", two(0xf000, 0x2400), two(0xffff, 0xffff), "" },
+
+{"pflush", two(0xf000, 0x3010), two(0xffc0, 0xfe10), "T3T9" },
+{"pflush", two(0xf000, 0x3810), two(0xffc0, 0xfe10), "T3T9&s" },
+{"pflush", two(0xf000, 0x3008), two(0xffc0, 0xfe18), "D3T9" },
+{"pflush", two(0xf000, 0x3808), two(0xffc0, 0xfe18), "D3T9&s" },
+{"pflush", two(0xf000, 0x3000), two(0xffc0, 0xfe1e), "f3T9" },
+{"pflush", two(0xf000, 0x3800), two(0xffc0, 0xfe1e), "f3T9&s" },
+
+{"pflushs", two(0xf000, 0x3410), two(0xfff8, 0xfe10), "T3T9" },
+{"pflushs", two(0xf000, 0x3c10), two(0xfff8, 0xfe00), "T3T9&s" },
+{"pflushs", two(0xf000, 0x3408), two(0xfff8, 0xfe18), "D3T9" },
+{"pflushs", two(0xf000, 0x3c08), two(0xfff8, 0xfe18), "D3T9&s" },
+{"pflushs", two(0xf000, 0x3400), two(0xfff8, 0xfe1e), "f3T9" },
+{"pflushs", two(0xf000, 0x3c00), two(0xfff8, 0xfe1e), "f3T9&s"},
+
+{"pflushr", two(0xf000, 0xa000), two(0xffc0, 0xffff), "|s" },
+
+{"ploadr", two(0xf000, 0x2210), two(0xffc0, 0xfff0), "T3&s" },
+{"ploadr", two(0xf000, 0x2208), two(0xffc0, 0xfff8), "D3&s" },
+{"ploadr", two(0xf000, 0x2200), two(0xffc0, 0xfffe), "f3&s" },
+{"ploadw", two(0xf000, 0x2010), two(0xffc0, 0xfff0), "T3&s" },
+{"ploadw", two(0xf000, 0x2008), two(0xffc0, 0xfff8), "D3&s" },
+{"ploadw", two(0xf000, 0x2000), two(0xffc0, 0xfffe), "f3&s" },
+
+/* TC, CRP, DRP, SRP, CAL, VAL, SCC, AC */
+{"pmove", two(0xf000, 0x4000), two(0xffc0, 0xe3ff), "*sP8" },
+{"pmove", two(0xf000, 0x4200), two(0xffc0, 0xe3ff), "P8%s" },
+{"pmove", two(0xf000, 0x4000), two(0xffc0, 0xe3ff), "|sW8" },
+{"pmove", two(0xf000, 0x4200), two(0xffc0, 0xe3ff), "W8~s" },
+
+/* BADx, BACx */
+{"pmove", two(0xf000, 0x6200), two(0xffc0, 0xe3e3), "*sX3" },
+{"pmove", two(0xf000, 0x6000), two(0xffc0, 0xe3e3), "X3%s" },
+
+/* PSR, PCSR */
+/* {"pmove", two(0xf000, 0x6100), two(oxffc0, oxffff), "*sZ8" }, */
+{"pmove", two(0xf000, 0x6000), two(0xffc0, 0xffff), "*sY8" },
+{"pmove", two(0xf000, 0x6200), two(0xffc0, 0xffff), "Y8%s" },
+{"pmove", two(0xf000, 0x6600), two(0xffc0, 0xffff), "Z8%s" },
+
+{"prestore", one(0xf140), one(0xffc0), "&s"},
+{"prestore", one(0xf158), one(0xfff8), "+s"},
+{"psave", one(0xf100), one(0xffc0), "&s"},
+{"psave", one(0xf100), one(0xffc0), "+s"},
+
+{"psac", two(0xf040, 0x0007), two(0xffc0, 0xffff), "@s"},
+{"psas", two(0xf040, 0x0006), two(0xffc0, 0xffff), "@s"},
+{"psbc", two(0xf040, 0x0001), two(0xffc0, 0xffff), "@s"},
+{"psbs", two(0xf040, 0x0000), two(0xffc0, 0xffff), "@s"},
+{"pscc", two(0xf040, 0x000f), two(0xffc0, 0xffff), "@s"},
+{"pscs", two(0xf040, 0x000e), two(0xffc0, 0xffff), "@s"},
+{"psgc", two(0xf040, 0x000d), two(0xffc0, 0xffff), "@s"},
+{"psgs", two(0xf040, 0x000c), two(0xffc0, 0xffff), "@s"},
+{"psic", two(0xf040, 0x000b), two(0xffc0, 0xffff), "@s"},
+{"psis", two(0xf040, 0x000a), two(0xffc0, 0xffff), "@s"},
+{"pslc", two(0xf040, 0x0003), two(0xffc0, 0xffff), "@s"},
+{"psls", two(0xf040, 0x0002), two(0xffc0, 0xffff), "@s"},
+{"pssc", two(0xf040, 0x0005), two(0xffc0, 0xffff), "@s"},
+{"psss", two(0xf040, 0x0004), two(0xffc0, 0xffff), "@s"},
+{"pswc", two(0xf040, 0x0009), two(0xffc0, 0xffff), "@s"},
+{"psws", two(0xf040, 0x0008), two(0xffc0, 0xffff), "@s"},
+
+{"ptestr", two(0xf000, 0x8210), two(0xffc0, 0xe3f0), "T3&sQ8" },
+{"ptestr", two(0xf000, 0x8310), two(0xffc0, 0xe310), "T3&sQ8A9" },
+{"ptestr", two(0xf000, 0x8208), two(0xffc0, 0xe3f8), "D3&sQ8" },
+{"ptestr", two(0xf000, 0x8308), two(0xffc0, 0xe318), "D3&sQ8A9" },
+{"ptestr", two(0xf000, 0x8200), two(0xffc0, 0xe3fe), "f3&sQ8" },
+{"ptestr", two(0xf000, 0x8300), two(0xffc0, 0xe31e), "f3&sQ8A9" },
+
+{"ptestw", two(0xf000, 0x8010), two(0xffc0, 0xe3f0), "T3&sQ8" },
+{"ptestw", two(0xf000, 0x8110), two(0xffc0, 0xe310), "T3&sQ8A9" },
+{"ptestw", two(0xf000, 0x8008), two(0xffc0, 0xe3f8), "D3&sQ8" },
+{"ptestw", two(0xf000, 0x8108), two(0xffc0, 0xe318), "D3&sQ8A9" },
+{"ptestw", two(0xf000, 0x8000), two(0xffc0, 0xe3fe), "f3&sQ8" },
+{"ptestw", two(0xf000, 0x8100), two(0xffc0, 0xe31e), "f3&sQ8A9" },
+
+{"ptrapacw", two(0xf07a, 0x0007), two(0xffff, 0xffff), "#w"},
+{"ptrapacl", two(0xf07b, 0x0007), two(0xffff, 0xffff), "#l"},
+{"ptrapac", two(0xf07c, 0x0007), two(0xffff, 0xffff), ""},
+
+{"ptrapasw", two(0xf07a, 0x0006), two(0xffff, 0xffff), "#w"},
+{"ptrapasl", two(0xf07b, 0x0006), two(0xffff, 0xffff), "#l"},
+{"ptrapas", two(0xf07c, 0x0006), two(0xffff, 0xffff), ""},
+
+{"ptrapbcw", two(0xf07a, 0x0001), two(0xffff, 0xffff), "#w"},
+{"ptrapbcl", two(0xf07b, 0x0001), two(0xffff, 0xffff), "#l"},
+{"ptrapbc", two(0xf07c, 0x0001), two(0xffff, 0xffff), ""},
+
+{"ptrapbsw", two(0xf07a, 0x0000), two(0xffff, 0xffff), "#w"},
+{"ptrapbsl", two(0xf07b, 0x0000), two(0xffff, 0xffff), "#l"},
+{"ptrapbs", two(0xf07c, 0x0000), two(0xffff, 0xffff), ""},
+
+{"ptrapccw", two(0xf07a, 0x000f), two(0xffff, 0xffff), "#w"},
+{"ptrapccl", two(0xf07b, 0x000f), two(0xffff, 0xffff), "#l"},
+{"ptrapcc", two(0xf07c, 0x000f), two(0xffff, 0xffff), ""},
+
+{"ptrapcsw", two(0xf07a, 0x000e), two(0xffff, 0xffff), "#w"},
+{"ptrapcsl", two(0xf07b, 0x000e), two(0xffff, 0xffff), "#l"},
+{"ptrapcs", two(0xf07c, 0x000e), two(0xffff, 0xffff), ""},
+
+{"ptrapgcw", two(0xf07a, 0x000d), two(0xffff, 0xffff), "#w"},
+{"ptrapgcl", two(0xf07b, 0x000d), two(0xffff, 0xffff), "#l"},
+{"ptrapgc", two(0xf07c, 0x000d), two(0xffff, 0xffff), ""},
+
+{"ptrapgsw", two(0xf07a, 0x000c), two(0xffff, 0xffff), "#w"},
+{"ptrapgsl", two(0xf07b, 0x000c), two(0xffff, 0xffff), "#l"},
+{"ptrapgs", two(0xf07c, 0x000c), two(0xffff, 0xffff), ""},
+
+{"ptrapicw", two(0xf07a, 0x000b), two(0xffff, 0xffff), "#w"},
+{"ptrapicl", two(0xf07b, 0x000b), two(0xffff, 0xffff), "#l"},
+{"ptrapic", two(0xf07c, 0x000b), two(0xffff, 0xffff), ""},
+
+{"ptrapisw", two(0xf07a, 0x000a), two(0xffff, 0xffff), "#w"},
+{"ptrapisl", two(0xf07b, 0x000a), two(0xffff, 0xffff), "#l"},
+{"ptrapis", two(0xf07c, 0x000a), two(0xffff, 0xffff), ""},
+
+{"ptraplcw", two(0xf07a, 0x0003), two(0xffff, 0xffff), "#w"},
+{"ptraplcl", two(0xf07b, 0x0003), two(0xffff, 0xffff), "#l"},
+{"ptraplc", two(0xf07c, 0x0003), two(0xffff, 0xffff), ""},
+
+{"ptraplsw", two(0xf07a, 0x0002), two(0xffff, 0xffff), "#w"},
+{"ptraplsl", two(0xf07b, 0x0002), two(0xffff, 0xffff), "#l"},
+{"ptrapls", two(0xf07c, 0x0002), two(0xffff, 0xffff), ""},
+
+{"ptrapscw", two(0xf07a, 0x0005), two(0xffff, 0xffff), "#w"},
+{"ptrapscl", two(0xf07b, 0x0005), two(0xffff, 0xffff), "#l"},
+{"ptrapsc", two(0xf07c, 0x0005), two(0xffff, 0xffff), ""},
+
+{"ptrapssw", two(0xf07a, 0x0004), two(0xffff, 0xffff), "#w"},
+{"ptrapssl", two(0xf07b, 0x0004), two(0xffff, 0xffff), "#l"},
+{"ptrapss", two(0xf07c, 0x0004), two(0xffff, 0xffff), ""},
+
+{"ptrapwcw", two(0xf07a, 0x0009), two(0xffff, 0xffff), "#w"},
+{"ptrapwcl", two(0xf07b, 0x0009), two(0xffff, 0xffff), "#l"},
+{"ptrapwc", two(0xf07c, 0x0009), two(0xffff, 0xffff), ""},
+
+{"ptrapwsw", two(0xf07a, 0x0008), two(0xffff, 0xffff), "#w"},
+{"ptrapwsl", two(0xf07b, 0x0008), two(0xffff, 0xffff), "#l"},
+{"ptrapws", two(0xf07c, 0x0008), two(0xffff, 0xffff), ""},
+
+{"pvalid", two(0xf000, 0x2800), two(0xffc0, 0xffff), "Vs&s"},
+{"pvalid", two(0xf000, 0x2c00), two(0xffc0, 0xfff8), "A3&s" },
+
+#endif /* m68851 */
+
+};
+
+int numopcodes=sizeof(m68k_opcodes)/sizeof(m68k_opcodes[0]);
+
+struct m68k_opcode *endop = m68k_opcodes+sizeof(m68k_opcodes)/sizeof(m68k_opcodes[0]);
diff --git a/gnu/usr.bin/gas/config/m68k.c b/gnu/usr.bin/gas/config/m68k.c
new file mode 100644
index 00000000000..7401a91ed28
--- /dev/null
+++ b/gnu/usr.bin/gas/config/m68k.c
@@ -0,0 +1,3540 @@
+/* m68k.c All the m68020 specific stuff in one convenient, huge,
+ slow to compile, easy to find file.
+ Copyright (C) 1987 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <ctype.h>
+
+#include "m68k-opcode.h"
+#include "as.h"
+#include "obstack.h"
+#include "frags.h"
+#include "struc-symbol.h"
+#include "flonum.h"
+#include "expr.h"
+#include "hash.h"
+#include "md.h"
+#include "m68k.h"
+
+#ifdef M_SUN
+/* This variable contains the value to write out at the beginning of
+ the a.out file. The 2<<16 means that this is a 68020 file instead
+ of an old-style 68000 file */
+
+long omagic = 2<<16|OMAGIC; /* Magic byte for header file */
+#else
+long omagic = OMAGIC;
+#endif
+
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful */
+const char comment_chars[] = "|";
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that '/*' will always start a comment */
+const char line_comment_chars[] = "#";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+
+const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
+
+/* 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.
+ */
+
+void fix_new();
+void install_operand();
+void install_gen_operand();
+
+/* Its an arbitrary name: This means I don't approve of it */
+/* See flames below */
+struct obstack robyn;
+
+#define TAB(x,y) (((x)<<2)+(y))
+#define TABTYPE(xy) ((xy) >> 2)
+#define BYTE 0
+#define SHORT 1
+#define LONG 2
+#define SZ_UNDEF 3
+
+#define BRANCH 1
+#define FBRANCH 2
+#define PCREL 3
+#define BCC68000 4
+#define DBCC 5
+#define PCLEA 6
+
+/* BCC68000 is for patching in an extra jmp instruction for long offsets
+ on the 68000. The 68000 doesn't support long branches with branchs */
+
+/* This table desribes how you change sizes for the various types of variable
+ size expressions. This version only supports two kinds. */
+
+/* Note that calls to frag_var need to specify the maximum expansion needed */
+/* This is currently 10 bytes for DBCC */
+
+/* The fields are:
+ How far Forward this mode will reach:
+ How far Backward this mode will reach:
+ How many bytes this mode will add to the size of the frag
+ Which mode to go to if the offset won't fit in this one
+ */
+const relax_typeS
+md_relax_table[] = {
+{ 1, 1, 0, 0 }, /* First entries aren't used */
+{ 1, 1, 0, 0 }, /* For no good reason except */
+{ 1, 1, 0, 0 }, /* that the VAX doesn't either */
+{ 1, 1, 0, 0 },
+
+{ (127), (-128), 0, TAB(BRANCH,SHORT)},
+{ (32767), (-32768), 2, TAB(BRANCH,LONG) },
+{ 0, 0, 4, 0 },
+{ 1, 1, 0, 0 },
+
+{ 1, 1, 0, 0 }, /* FBRANCH doesn't come BYTE */
+{ (32767), (-32768), 2, TAB(FBRANCH,LONG)},
+{ 0, 0, 4, 0 },
+{ 1, 1, 0, 0 },
+
+{ 1, 1, 0, 0 }, /* PCREL doesn't come BYTE */
+{ (32767), (-32768), 2, TAB(PCREL,LONG)},
+{ 0, 0, 4, 0 },
+{ 1, 1, 0, 0 },
+
+{ (127), (-128), 0, TAB(BCC68000,SHORT)},
+{ (32767), (-32768), 2, TAB(BCC68000,LONG) },
+{ 0, 0, 6, 0 }, /* jmp long space */
+{ 1, 1, 0, 0 },
+
+{ 1, 1, 0, 0 }, /* DBCC doesn't come BYTE */
+{ (32767), (-32768), 2, TAB(DBCC,LONG) },
+{ 0, 0, 10, 0 }, /* bra/jmp long space */
+{ 1, 1, 0, 0 },
+
+{ 1, 1, 0, 0 }, /* PCLEA doesn't come BYTE */
+{ 32767, -32768, 2, TAB(PCLEA,LONG) },
+{ 0, 0, 6, 0 },
+{ 1, 1, 0, 0 },
+
+};
+
+void s_data1(), s_data2(), s_even(), s_space();
+void s_proc(), float_cons();
+
+/* These are the machine dependent pseudo-ops. These are included so
+ the assembler can work on the output from the SUN C compiler, which
+ generates these.
+ */
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ Integer arg to pass to the function
+ */
+const pseudo_typeS md_pseudo_table[] = {
+ { "data1", s_data1, 0 },
+ { "data2", s_data2, 0 },
+ { "even", s_even, 0 },
+ { "skip", s_space, 0 },
+ { "proc", s_proc, 0 },
+ { 0, 0, 0 }
+};
+
+
+/* #define isbyte(x) ((x)>=-128 && (x)<=127) */
+/* #define isword(x) ((x)>=-32768 && (x)<=32767) */
+
+#define issbyte(x) ((x)>=-128 && (x)<=127)
+#define isubyte(x) ((x)>=0 && (x)<=255)
+#define issword(x) ((x)>=-32768 && (x)<=32767)
+#define isuword(x) ((x)>=0 && (x)<=65535)
+
+#define isbyte(x) ((x)>=-128 && (x)<=255)
+#define isword(x) ((x)>=-32768 && (x)<=65535)
+#define islong(x) (1)
+
+extern char *input_line_pointer;
+
+/* Operands we can parse: (And associated modes)
+
+numb: 8 bit num
+numw: 16 bit num
+numl: 32 bit num
+dreg: data reg 0-7
+reg: address or data register
+areg: address register
+apc: address register, PC, ZPC or empty string
+num: 16 or 32 bit num
+num2: like num
+sz: w or l if omitted, l assumed
+scale: 1 2 4 or 8 if omitted, 1 assumed
+
+7.4 IMMED #num --> NUM
+0.? DREG dreg --> dreg
+1.? AREG areg --> areg
+2.? AINDR areg@ --> *(areg)
+3.? AINC areg@+ --> *(areg++)
+4.? ADEC areg@- --> *(--areg)
+5.? AOFF apc@(numw) --> *(apc+numw) -- empty string and ZPC not allowed here
+6.? AINDX apc@(num,reg:sz:scale) --> *(apc+num+reg*scale)
+6.? AINDX apc@(reg:sz:scale) --> same, with num=0
+6.? APODX apc@(num)@(num2,reg:sz:scale) --> *(*(apc+num)+num2+reg*scale)
+6.? APODX apc@(num)@(reg:sz:scale) --> same, with num2=0
+6.? AMIND apc@(num)@(num2) --> *(*(apc+num)+num2) (previous mode without an index reg)
+6.? APRDX apc@(num,reg:sz:scale)@(num2) --> *(*(apc+num+reg*scale)+num2)
+6.? APRDX apc@(reg:sz:scale)@(num2) --> same, with num=0
+7.0 ABSL num:sz --> *(num)
+ num --> *(num) (sz L assumed)
+*** MSCR otherreg --> Magic
+With -l option
+5.? AOFF apc@(num) --> *(apc+num) -- empty string and ZPC not allowed here still
+
+examples:
+ #foo #0x35 #12
+ d2
+ a4
+ a3@
+ a5@+
+ a6@-
+ a2@(12) pc@(14)
+ a1@(5,d2:w:1) @(45,d6:l:4)
+ pc@(a2) @(d4)
+ etc . . .
+
+
+#name@(numw) -->turn into PC rel mode
+apc@(num8,reg:sz:scale) --> *(apc+num8+reg*scale)
+
+*/
+
+#define IMMED 1
+#define DREG 2
+#define AREG 3
+#define AINDR 4
+#define ADEC 5
+#define AINC 6
+#define AOFF 7
+#define AINDX 8
+#define APODX 9
+#define AMIND 10
+#define APRDX 11
+#define ABSL 12
+#define MSCR 13
+#define REGLST 14
+
+#define FAIL 0
+#define OK 1
+
+/* DATA and ADDR have to be contiguous, so that reg-DATA gives 0-7==data reg,
+ 8-15==addr reg for operands that take both types */
+#define DATA 1 /* 1- 8 == data registers 0-7 */
+#define ADDR (DATA+8) /* 9-16 == address regs 0-7 */
+#define FPREG (ADDR+8) /* 17-24 Eight FP registers */
+#define COPNUM (FPREG+8) /* 25-32 Co-processor #1-#8 */
+
+#define PC (COPNUM+8) /* 33 Program counter */
+#define ZPC (PC+1) /* 34 Hack for Program space, but 0 addressing */
+#define SR (ZPC+1) /* 35 Status Reg */
+#define CCR (SR+1) /* 36 Condition code Reg */
+
+/* These have to be in order for the movec instruction to work. */
+#define USP (CCR+1) /* 37 User Stack Pointer */
+#define ISP (USP+1) /* 38 Interrupt stack pointer */
+#define SFC (ISP+1) /* 39 */
+#define DFC (SFC+1) /* 40 */
+#define CACR (DFC+1) /* 41 */
+#define VBR (CACR+1) /* 42 */
+#define CAAR (VBR+1) /* 43 */
+#define MSP (CAAR+1) /* 44 */
+
+#define FPI (MSP+1) /* 45 */
+#define FPS (FPI+1) /* 46 */
+#define FPC (FPS+1) /* 47 */
+/*
+ * these defines should be in m68k.c but
+ * i put them here to keep all the m68851 stuff
+ * together -rab
+ * JF--Make sure these #s don't clash with the ones in m68k.c
+ * That would be BAD.
+ */
+#define TC (FPC+1) /* 48 */
+#define DRP (TC+1) /* 49 */
+#define SRP (DRP+1) /* 50 */
+#define CRP (SRP+1) /* 51 */
+#define CAL (CRP+1) /* 52 */
+#define VAL (CAL+1) /* 53 */
+#define SCC (VAL+1) /* 54 */
+#define AC (SCC+1) /* 55 */
+#define BAD (AC+1) /* 56,57,58,59, 60,61,62,63 */
+#define BAC (BAD+8) /* 64,65,66,67, 68,69,70,71 */
+#define PSR (BAC+8) /* 72 */
+#define PCSR (PSR+1) /* 73 */
+
+
+/* Note that COPNUM==processor #1 -- COPNUM+7==#8, which stores as 000 */
+/* I think. . . */
+
+#define SP ADDR+7
+
+/* JF these tables here are for speed at the expense of size */
+/* You can replace them with the #if 0 versions if you really
+ need space and don't mind it running a bit slower */
+
+static char mklower_table[256];
+#define mklower(c) (mklower_table[(unsigned char)(c)])
+static char notend_table[256];
+static char alt_notend_table[256];
+#define notend(s) ( !(notend_table[(unsigned char)(*s)] || (*s==':' &&\
+ alt_notend_table[(unsigned char)(s[1])])))
+
+#if 0
+#define mklower(c) (isupper(c) ? tolower(c) : c)
+#endif
+
+
+struct m68k_exp {
+ char *e_beg;
+ char *e_end;
+ expressionS e_exp;
+ short e_siz; /* 0== default 1==short/byte 2==word 3==long */
+};
+
+/* Internal form of an operand. */
+struct m68k_op {
+ char *error; /* Couldn't parse it */
+ int mode; /* What mode this instruction is in. */
+ unsigned long int reg; /* Base register */
+ struct m68k_exp *con1;
+ int ireg; /* Index register */
+ int isiz; /* 0==unspec 1==byte(?) 2==short 3==long */
+ int imul; /* Multipy ireg by this (1,2,4,or 8) */
+ struct m68k_exp *con2;
+};
+
+/* internal form of a 68020 instruction */
+struct m68_it {
+ char *error;
+ char *args; /* list of opcode info */
+ int numargs;
+
+ int numo; /* Number of shorts in opcode */
+ short opcode[11];
+
+ struct m68k_op operands[6];
+
+ int nexp; /* number of exprs in use */
+ struct m68k_exp exprs[4];
+
+ int nfrag; /* Number of frags we have to produce */
+ struct {
+ int fragoff; /* Where in the current opcode[] the frag ends */
+ symbolS *fadd;
+ long int foff;
+ int fragty;
+ } fragb[4];
+
+ int nrel; /* Num of reloc strucs in use */
+ struct {
+ int n;
+ symbolS *add,
+ *sub;
+ long int off;
+ char wid;
+ char pcrel;
+ } reloc[5]; /* Five is enough??? */
+};
+
+struct m68_it the_ins; /* the instruction being assembled */
+
+
+/* Macros for adding things to the m68_it struct */
+
+#define addword(w) the_ins.opcode[the_ins.numo++]=(w)
+
+/* Like addword, but goes BEFORE general operands */
+#define insop(w) {int z;\
+ for(z=the_ins.numo;z>opcode->m_codenum;--z)\
+ the_ins.opcode[z]=the_ins.opcode[z-1];\
+ for(z=0;z<the_ins.nrel;z++)\
+ the_ins.reloc[z].n+=2;\
+ the_ins.opcode[opcode->m_codenum]=w;\
+ the_ins.numo++;\
+}
+
+
+#define add_exp(beg,end) (\
+ the_ins.exprs[the_ins.nexp].e_beg=beg,\
+ the_ins.exprs[the_ins.nexp].e_end=end,\
+ &the_ins.exprs[the_ins.nexp++]\
+)
+
+
+/* The numo+1 kludge is so we can hit the low order byte of the prev word. Blecch*/
+#define add_fix(width,exp,pc_rel) {\
+ the_ins.reloc[the_ins.nrel].n= ((width)=='B') ? (the_ins.numo*2-1) : \
+ (((width)=='b') ? ((the_ins.numo-1)*2) : (the_ins.numo*2));\
+ the_ins.reloc[the_ins.nrel].add=adds((exp));\
+ the_ins.reloc[the_ins.nrel].sub=subs((exp));\
+ the_ins.reloc[the_ins.nrel].off=offs((exp));\
+ the_ins.reloc[the_ins.nrel].wid=width;\
+ the_ins.reloc[the_ins.nrel++].pcrel=pc_rel;\
+}
+
+#define add_frag(add,off,type) {\
+ the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo;\
+ the_ins.fragb[the_ins.nfrag].fadd=add;\
+ the_ins.fragb[the_ins.nfrag].foff=off;\
+ the_ins.fragb[the_ins.nfrag++].fragty=type;\
+}
+
+#define isvar(exp) ((exp) && (adds(exp) || subs(exp)))
+
+#define seg(exp) ((exp)->e_exp.X_seg)
+#define adds(exp) ((exp)->e_exp.X_add_symbol)
+#define subs(exp) ((exp)->e_exp.X_subtract_symbol)
+#define offs(exp) ((exp)->e_exp.X_add_number)
+
+
+struct m68_incant {
+ char *m_operands;
+ unsigned long m_opcode;
+ short m_opnum;
+ short m_codenum;
+ struct m68_incant *m_next;
+};
+
+#define getone(x) ((((x)->m_opcode)>>16)&0xffff)
+#define gettwo(x) (((x)->m_opcode)&0xffff)
+
+
+/* JF modified this to handle cases where the first part of a symbol name
+ looks like a register */
+
+int
+m68k_reg_parse(ccp)
+register char **ccp;
+{
+ register char c1,
+ c2,
+ c3,
+ c4;
+ register int n = 0,
+ ret = FAIL;
+
+ c1=mklower(ccp[0][0]);
+#ifdef REGISTER_PREFIX
+ if(c1!=REGISTER_PREFIX)
+ return FAIL;
+ c1=mklower(ccp[0][1]);
+ c2=mklower(ccp[0][2]);
+ c3=mklower(ccp[0][3]);
+ c4=mklower(ccp[0][4]);
+#else
+ c2=mklower(ccp[0][1]);
+ c3=mklower(ccp[0][2]);
+ c4=mklower(ccp[0][3]);
+#endif
+ switch(c1) {
+ case 'a':
+ if(c2>='0' && c2<='7') {
+ n=2;
+ ret=ADDR+c2-'0';
+ }
+#ifdef m68851
+ else if (c2 == 'c') {
+ n = 2;
+ ret = AC;
+ }
+#endif
+ break;
+#ifdef m68851
+ case 'b':
+ if (c2 == 'a') {
+ if (c3 == 'd') {
+ if (c4 >= '0' && c4 <= '7') {
+ n = 4;
+ ret = BAD + c4 - '0';
+ }
+ }
+ if (c3 == 'c') {
+ if (c4 >= '0' && c4 <= '7') {
+ n = 4;
+ ret = BAC + c4 - '0';
+ }
+ }
+ }
+ break;
+#endif
+ case 'c':
+#ifdef m68851
+ if (c2 == 'a' && c3 == 'l') {
+ n = 3;
+ ret = CAL;
+ } else
+#endif
+ /* This supports both CCR and CC as the ccr reg. */
+ if(c2=='c' && c3=='r') {
+ n=3;
+ ret = CCR;
+ } else if(c2=='c') {
+ n=2;
+ ret = CCR;
+ } else if(c2=='a' && (c3=='a' || c3=='c') && c4=='r') {
+ n=4;
+ ret = c3=='a' ? CAAR : CACR;
+ }
+#ifdef m68851
+ else if (c2 == 'r' && c3 == 'p') {
+ n = 3;
+ ret = (CRP);
+ }
+#endif
+ break;
+ case 'd':
+ if(c2>='0' && c2<='7') {
+ n=2;
+ ret = DATA+c2-'0';
+ } else if(c2=='f' && c3=='c') {
+ n=3;
+ ret = DFC;
+ }
+#ifdef m68851
+ else if (c2 == 'r' && c3 == 'p') {
+ n = 3;
+ ret = (DRP);
+ }
+#endif
+ break;
+ case 'f':
+ if(c2=='p') {
+ if(c3>='0' && c3<='7') {
+ n=3;
+ ret = FPREG+c3-'0';
+ if(c4==':')
+ ccp[0][3]=',';
+ } else if(c3=='i') {
+ n=3;
+ ret = FPI;
+ } else if(c3=='s') {
+ n= (c4 == 'r' ? 4 : 3);
+ ret = FPS;
+ } else if(c3=='c') {
+ n= (c4 == 'r' ? 4 : 3);
+ ret = FPC;
+ }
+ }
+ break;
+ case 'i':
+ if(c2=='s' && c3=='p') {
+ n=3;
+ ret = ISP;
+ }
+ break;
+ case 'm':
+ if(c2=='s' && c3=='p') {
+ n=3;
+ ret = MSP;
+ }
+ break;
+ case 'p':
+ if(c2=='c') {
+#ifdef m68851
+ if(c3 == 's' && c4=='r') {
+ n=4;
+ ret = (PCSR);
+ } else
+#endif
+ {
+ n=2;
+ ret = PC;
+ }
+ }
+#ifdef m68851
+ else if (c2 == 's' && c3 == 'r') {
+ n = 3;
+ ret = (PSR);
+ }
+#endif
+ break;
+ case 's':
+#ifdef m68851
+ if (c2 == 'c' && c3 == 'c') {
+ n = 3;
+ ret = (SCC);
+ } else if (c2 == 'r' && c3 == 'p') {
+ n = 3;
+ ret = (SRP);
+ } else
+#endif
+ if(c2=='r') {
+ n=2;
+ ret = SR;
+ } else if(c2=='p') {
+ n=2;
+ ret = ADDR+7;
+ } else if(c2=='f' && c3=='c') {
+ n=3;
+ ret = SFC;
+ }
+ break;
+#ifdef m68851
+ case 't':
+ if(c2 == 'c') {
+ n=2;
+ ret=TC;
+ }
+ break;
+#endif
+ case 'u':
+ if(c2=='s' && c3=='p') {
+ n=3;
+ ret = USP;
+ }
+ break;
+ case 'v':
+#ifdef m68851
+ if (c2 == 'a' && c3 == 'l') {
+ n = 3;
+ ret = (VAL);
+ } else
+#endif
+ if(c2=='b' && c3=='r') {
+ n=3;
+ ret = VBR;
+ }
+ break;
+ case 'z':
+ if(c2=='p' && c3=='c') {
+ n=3;
+ ret = ZPC;
+ }
+ break;
+ default:
+ break;
+ }
+ if(n) {
+#ifdef REGISTER_PREFIX
+ n++;
+#endif
+ if(isalnum(ccp[0][n]) || ccp[0][n]=='_')
+ ret=FAIL;
+ else
+ ccp[0]+=n;
+ } else
+ ret = FAIL;
+ return ret;
+}
+
+#define SKIP_WHITE() { str++; if(*str==' ') str++;}
+
+int
+m68k_ip_op(str,opP)
+char *str;
+register struct m68k_op *opP;
+{
+ char *strend;
+ long i;
+ char *parse_index();
+
+ if(*str==' ')
+ str++;
+ /* Find the end of the string */
+ if(!*str) {
+ /* Out of gas */
+ opP->error="Missing operand";
+ return FAIL;
+ }
+ for(strend=str;*strend;strend++)
+ ;
+ --strend;
+
+ /* Guess what: A constant. Shar and enjoy */
+ if(*str=='#') {
+ str++;
+ opP->con1=add_exp(str,strend);
+ opP->mode=IMMED;
+ return OK;
+ }
+ i=m68k_reg_parse(&str);
+ if((i==FAIL || *str!='\0') && *str!='@') {
+ char *stmp;
+ char *index();
+
+ if(i!=FAIL && (*str=='/' || *str=='-')) {
+ opP->mode=REGLST;
+ return get_regs(i,str,opP);
+ }
+ if(stmp=index(str,'@')) {
+ opP->con1=add_exp(str,stmp-1);
+ if(stmp==strend) {
+ opP->mode=AINDX;
+ return OK;
+ }
+ stmp++;
+ if(*stmp++!='(' || *strend--!=')') {
+ opP->error="Malformed operand";
+ return FAIL;
+ }
+ i=try_index(&stmp,opP);
+ opP->con2=add_exp(stmp,strend);
+ if(i==FAIL) opP->mode=AMIND;
+ else opP->mode=APODX;
+ return OK;
+ }
+ opP->mode=ABSL;
+ opP->con1=add_exp(str,strend);
+ return OK;
+ }
+ opP->reg=i;
+ if(*str=='\0') {
+ if(i>=DATA+0 && i<=DATA+7)
+ opP->mode=DREG;
+ else if(i>=ADDR+0 && i<=ADDR+7)
+ opP->mode=AREG;
+ else
+ opP->mode=MSCR;
+ return OK;
+ }
+ if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) { /* Can't indirect off non address regs */
+ opP->error="Invalid indirect register";
+ return FAIL;
+ }
+ if(*str!='@')
+ abort();
+ str++;
+ switch(*str) {
+ case '\0':
+ opP->mode=AINDR;
+ return OK;
+ case '-':
+ opP->mode=ADEC;
+ return OK;
+ case '+':
+ opP->mode=AINC;
+ return OK;
+ case '(':
+ str++;
+ break;
+ default:
+ opP->error="Junk after indirect";
+ return FAIL;
+ }
+ /* Some kind of indexing involved. Lets find out how bad it is */
+ i=try_index(&str,opP);
+ /* Didn't start with an index reg, maybe its offset or offset,reg */
+ if(i==FAIL) {
+ char *beg_str;
+
+ beg_str=str;
+ for(i=1;i;) {
+ switch(*str++) {
+ case '\0':
+ opP->error="Missing )";
+ return FAIL;
+ case ',': i=0; break;
+ case '(': i++; break;
+ case ')': --i; break;
+ }
+ }
+ /* if(str[-3]==':') {
+ int siz;
+
+ switch(str[-2]) {
+ case 'b':
+ case 'B':
+ siz=1;
+ break;
+ case 'w':
+ case 'W':
+ siz=2;
+ break;
+ case 'l':
+ case 'L':
+ siz=3;
+ break;
+ default:
+ opP->error="Specified size isn't :w or :l";
+ return FAIL;
+ }
+ opP->con1=add_exp(beg_str,str-4);
+ opP->con1->e_siz=siz;
+ } else */
+ opP->con1=add_exp(beg_str,str-2);
+ /* Should be offset,reg */
+ if(str[-1]==',') {
+ i=try_index(&str,opP);
+ if(i==FAIL) {
+ opP->error="Malformed index reg";
+ return FAIL;
+ }
+ }
+ }
+ /* We've now got offset) offset,reg) or reg) */
+
+ if(*str=='\0') {
+ /* Th-the-thats all folks */
+ if(opP->reg==FAIL) opP->mode=AINDX; /* Other form of indirect */
+ else if(opP->ireg==FAIL) opP->mode=AOFF;
+ else opP->mode=AINDX;
+ return OK;
+ }
+ /* Next thing had better be another @ */
+ if(*str!='@' || str[1]!='(') {
+ opP->error="junk after indirect";
+ return FAIL;
+ }
+ str+=2;
+ if(opP->ireg!=FAIL) {
+ opP->mode=APRDX;
+ i=try_index(&str,opP);
+ if(i!=FAIL) {
+ opP->error="Two index registers! not allowed!";
+ return FAIL;
+ }
+ } else
+ i=try_index(&str,opP);
+ if(i==FAIL) {
+ char *beg_str;
+
+ beg_str=str;
+ for(i=1;i;) {
+ switch(*str++) {
+ case '\0':
+ opP->error="Missing )";
+ return FAIL;
+ case ',': i=0; break;
+ case '(': i++; break;
+ case ')': --i; break;
+ }
+ }
+ opP->con2=add_exp(beg_str,str-2);
+ if(str[-1]==',') {
+ if(opP->ireg!=FAIL) {
+ opP->error="Can't have two index regs";
+ return FAIL;
+ }
+ i=try_index(&str,opP);
+ if(i==FAIL) {
+ opP->error="malformed index reg";
+ return FAIL;
+ }
+ opP->mode=APODX;
+ } else if(opP->ireg!=FAIL)
+ opP->mode=APRDX;
+ else
+ opP->mode=AMIND;
+ } else
+ opP->mode=APODX;
+ if(*str!='\0') {
+ opP->error="Junk after indirect";
+ return FAIL;
+ }
+ return OK;
+}
+
+int
+try_index(s,opP)
+char **s;
+struct m68k_op *opP;
+{
+ register int i;
+ char *ss;
+#define SKIP_W() { ss++; if(*ss==' ') ss++;}
+
+ ss= *s;
+ /* SKIP_W(); */
+ i=m68k_reg_parse(&ss);
+ if(!(i>=DATA+0 && i<=ADDR+7)) { /* if i is not DATA or ADDR reg */
+ *s=ss;
+ return FAIL;
+ }
+ opP->ireg=i;
+ /* SKIP_W(); */
+ if(*ss==')') {
+ opP->isiz=0;
+ opP->imul=1;
+ SKIP_W();
+ *s=ss;
+ return OK;
+ }
+ if(*ss!=':') {
+ opP->error="Missing : in index register";
+ *s=ss;
+ return FAIL;
+ }
+ SKIP_W();
+ switch(*ss) {
+ case 'w':
+ case 'W':
+ opP->isiz=2;
+ break;
+ case 'l':
+ case 'L':
+ opP->isiz=3;
+ break;
+ default:
+ opP->error="Index register size spec not :w or :l";
+ *s=ss;
+ return FAIL;
+ }
+ SKIP_W();
+ if(*ss==':') {
+ SKIP_W();
+ switch(*ss) {
+ case '1':
+ case '2':
+ case '4':
+ case '8':
+ opP->imul= *ss-'0';
+ break;
+ default:
+ opP->error="index multiplier not 1, 2, 4 or 8";
+ *s=ss;
+ return FAIL;
+ }
+ SKIP_W();
+ } else opP->imul=1;
+ if(*ss!=')') {
+ opP->error="Missing )";
+ *s=ss;
+ return FAIL;
+ }
+ SKIP_W();
+ *s=ss;
+ return OK;
+}
+
+#ifdef TEST1 /* TEST1 tests m68k_ip_op(), which parses operands */
+main()
+{
+ char buf[128];
+ struct m68k_op thark;
+
+ for(;;) {
+ if(!gets(buf))
+ break;
+ bzero(&thark,sizeof(thark));
+ if(!m68k_ip_op(buf,&thark)) printf("FAIL:");
+ if(thark.error)
+ printf("op1 error %s in %s\n",thark.error,buf);
+ printf("mode %d, reg %d, ",thark.mode,thark.reg);
+ if(thark.b_const)
+ printf("Constant: '%.*s',",1+thark.e_const-thark.b_const,thark.b_const);
+ printf("ireg %d, isiz %d, imul %d ",thark.ireg,thark.isiz,thark.imul);
+ if(thark.b_iadd)
+ printf("Iadd: '%.*s'",1+thark.e_iadd-thark.b_iadd,thark.b_iadd);
+ printf("\n");
+ }
+ exit(0);
+}
+
+#endif
+
+
+static struct hash_control* op_hash = NULL; /* handle of the OPCODE hash table
+ NULL means any use before m68_ip_begin()
+ will crash */
+
+
+/*
+ * m 6 8 _ i p ( )
+ *
+ * This converts a string into a 68k instruction.
+ * The string must be a bare single instruction in sun format
+ * with RMS-style 68020 indirects
+ * (example: )
+ *
+ * It provides some error messages: at most one fatal error message (which
+ * stops the scan) and at most one warning message for each operand.
+ * The 68k instruction is returned in exploded form, since we have no
+ * knowledge of how you parse (or evaluate) your expressions.
+ * We do however strip off and decode addressing modes and operation
+ * mnemonic.
+ *
+ * This function's value is a string. If it is not "" then an internal
+ * logic error was found: read this code to assign meaning to the string.
+ * 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 m86_ip_begin() once and m86_ip_end() never before using
+ * this function.
+ */
+
+/* JF this function no longer returns a useful value. Sorry */
+void
+m68_ip (instring)
+char *instring;
+{
+ register char *p;
+ register struct m68k_op *opP;
+ register struct m68_incant *opcode;
+ register char *s;
+ register int tmpreg,
+ baseo,
+ outro,
+ nextword;
+ int siz1,
+ siz2;
+ char c;
+ int losing;
+ int opsfound;
+ char *crack_operand();
+ LITTLENUM_TYPE words[6];
+ LITTLENUM_TYPE *wordp;
+
+ if (*instring == ' ')
+ instring++; /* skip leading whitespace */
+
+ /* Scan up to end of operation-code, which MUST end in end-of-string
+ or exactly 1 space. */
+ for (p = instring; *p != '\0'; p++)
+ if (*p == ' ')
+ break;
+
+
+ if (p == instring) {
+ the_ins.error = "No operator";
+ the_ins.opcode[0] = NULL;
+ /* the_ins.numo=1; */
+ return;
+ }
+
+ /* p now points to the end of the opcode name, probably whitespace.
+ make sure the name is null terminated by clobbering the whitespace,
+ look it up in the hash table, then fix it back. */
+ c = *p;
+ *p = '\0';
+ opcode = (struct m68_incant *)hash_find (op_hash, instring);
+ *p = c;
+
+ if (opcode == NULL) {
+ the_ins.error = "Unknown operator";
+ the_ins.opcode[0] = NULL;
+ /* the_ins.numo=1; */
+ return;
+ }
+
+ /* found a legitimate opcode, start matching operands */
+ for(opP= &the_ins.operands[0];*p;opP++) {
+ p = crack_operand (p, opP);
+ if(opP->error) {
+ the_ins.error=opP->error;
+ return;
+ }
+ }
+
+ opsfound=opP- &the_ins.operands[0];
+ /* This ugly hack is to support the floating pt opcodes in their standard form */
+ /* Essentially, we fake a first enty of type COP#1 */
+ if(opcode->m_operands[0]=='I') {
+ int n;
+
+ for(n=opsfound;n>0;--n)
+ the_ins.operands[n]=the_ins.operands[n-1];
+
+ /* bcopy((char *)(&the_ins.operands[0]),(char *)(&the_ins.operands[1]),opsfound*sizeof(the_ins.operands[0])); */
+ bzero((char *)(&the_ins.operands[0]),sizeof(the_ins.operands[0]));
+ the_ins.operands[0].mode=MSCR;
+ the_ins.operands[0].reg=COPNUM; /* COP #1 */
+ opsfound++;
+ }
+ /* We've got the operands. Find an opcode that'll
+ accept them */
+ for(losing=0;;) {
+ if(opsfound!=opcode->m_opnum)
+ losing++;
+ else for(s=opcode->m_operands,opP= &the_ins.operands[0];*s && !losing;s+=2,opP++) {
+ /* Warning: this switch is huge! */
+ /* I've tried to organize the cases into this order:
+ non-alpha first, then alpha by letter. lower-case goes directly
+ before uppercase counterpart. */
+ /* Code with multiple case ...: gets sorted by the lowest case ...
+ it belongs to. I hope this makes sense. */
+ switch(*s) {
+ case '!':
+ if(opP->mode==MSCR || opP->mode==IMMED ||
+ opP->mode==DREG || opP->mode==AREG || opP->mode==AINC || opP->mode==ADEC || opP->mode==REGLST)
+ losing++;
+ break;
+
+ case '#':
+ if(opP->mode!=IMMED)
+ losing++;
+ else {
+ long t;
+
+ t=get_num(opP->con1,80);
+ if(s[1]=='b' && !isbyte(t))
+ losing++;
+ else if(s[1]=='w' && !isword(t))
+ losing++;
+ }
+ break;
+
+ case '^':
+ case 'T':
+ if(opP->mode!=IMMED)
+ losing++;
+ break;
+
+ case '$':
+ if(opP->mode==MSCR || opP->mode==AREG ||
+ opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST)
+ losing++;
+ break;
+
+ case '%':
+ if(opP->mode==MSCR || opP->reg==PC ||
+ opP->reg==ZPC || opP->mode==REGLST)
+ losing++;
+ break;
+
+
+ case '&':
+ if(opP->mode==MSCR || opP->mode==DREG ||
+ opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC ||
+ opP->mode==AINC || opP->mode==ADEC || opP->mode==REGLST)
+ losing++;
+ break;
+
+ case '*':
+ if(opP->mode==MSCR || opP->mode==REGLST)
+ losing++;
+ break;
+
+ case '+':
+ if(opP->mode!=AINC)
+ losing++;
+ break;
+
+ case '-':
+ if(opP->mode!=ADEC)
+ losing++;
+ break;
+
+ case '/':
+ if(opP->mode==MSCR || opP->mode==AREG ||
+ opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->mode==REGLST)
+ losing++;
+ break;
+
+ case ';':
+ if(opP->mode==MSCR || opP->mode==AREG || opP->mode==REGLST)
+ losing++;
+ break;
+
+ case '?':
+ if(opP->mode==MSCR || opP->mode==AREG ||
+ opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->reg==PC ||
+ opP->reg==ZPC || opP->mode==REGLST)
+ losing++;
+ break;
+
+ case '@':
+ if(opP->mode==MSCR || opP->mode==AREG ||
+ opP->mode==IMMED || opP->mode==REGLST)
+ losing++;
+ break;
+
+ case '~': /* For now! (JF FOO is this right?) */
+ if(opP->mode==MSCR || opP->mode==DREG ||
+ opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST)
+ losing++;
+ break;
+
+ case 'A':
+ if(opP->mode!=AREG)
+ losing++;
+ break;
+
+ case 'B': /* FOO */
+ if(opP->mode!=ABSL)
+ losing++;
+ break;
+
+ case 'C':
+ if(opP->mode!=MSCR || opP->reg!=CCR)
+ losing++;
+ break;
+
+ case 'd': /* FOO This mode is a KLUDGE!! */
+ if(opP->mode!=AOFF && (opP->mode!=ABSL ||
+ opP->con1->e_beg[0]!='(' || opP->con1->e_end[0]!=')'))
+ losing++;
+ break;
+
+ case 'D':
+ if(opP->mode!=DREG)
+ losing++;
+ break;
+
+ case 'F':
+ if(opP->mode!=MSCR || opP->reg<(FPREG+0) || opP->reg>(FPREG+7))
+ losing++;
+ break;
+
+ case 'I':
+ if(opP->mode!=MSCR || opP->reg<COPNUM ||
+ opP->reg>=COPNUM+7)
+ losing++;
+ break;
+
+ case 'J':
+ if(opP->mode!=MSCR || opP->reg<USP || opP->reg>MSP)
+ losing++;
+ break;
+
+ case 'k':
+ if(opP->mode!=IMMED)
+ losing++;
+ break;
+
+ case 'l':
+ case 'L':
+ if(opP->mode==DREG || opP->mode==AREG || opP->mode==FPREG) {
+ if(s[1]=='8')
+ losing++;
+ else {
+ opP->mode=REGLST;
+ opP->reg=1<<(opP->reg-DATA);
+ }
+ } else if(opP->mode!=REGLST) {
+ losing++;
+ } else if(s[1]=='8' && opP->reg&0x0FFffFF)
+ losing++;
+ else if(s[1]=='3' && opP->reg&0x7000000)
+ losing++;
+ break;
+
+ case 'M':
+ if(opP->mode!=IMMED)
+ losing++;
+ else {
+ long t;
+
+ t=get_num(opP->con1,80);
+ if(!issbyte(t) || isvar(opP->con1))
+ losing++;
+ }
+ break;
+
+ case 'O':
+ if(opP->mode!=DREG && opP->mode!=IMMED)
+ losing++;
+ break;
+
+ case 'Q':
+ if(opP->mode!=IMMED)
+ losing++;
+ else {
+ long t;
+
+ t=get_num(opP->con1,80);
+ if(t<1 || t>8 || isvar(opP->con1))
+ losing++;
+ }
+ break;
+
+ case 'R':
+ if(opP->mode!=DREG && opP->mode!=AREG)
+ losing++;
+ break;
+
+ case 's':
+ if(opP->mode!=MSCR || !(opP->reg==FPI || opP->reg==FPS || opP->reg==FPC))
+ losing++;
+ break;
+
+ case 'S':
+ if(opP->mode!=MSCR || opP->reg!=SR)
+ losing++;
+ break;
+
+ case 'U':
+ if(opP->mode!=MSCR || opP->reg!=USP)
+ losing++;
+ break;
+
+ /* JF these are out of order. We could put them
+ in order if we were willing to put up with
+ bunches of #ifdef m68851s in the code */
+#ifdef m68851
+ /* Memory addressing mode used by pflushr */
+ case '|':
+ if(opP->mode==MSCR || opP->mode==DREG ||
+ opP->mode==AREG || opP->mode==REGLST)
+ losing++;
+ break;
+
+ case 'f':
+ if (opP->mode != MSCR || (opP->reg != SFC && opP->reg != DFC))
+ losing++;
+ break;
+
+ case 'P':
+ if (opP->mode != MSCR || (opP->reg != TC && opP->reg != CAL &&
+ opP->reg != VAL && opP->reg != SCC && opP->reg != AC))
+ losing++;
+ break;
+
+ case 'V':
+ if (opP->reg != VAL)
+ losing++;
+ break;
+
+ case 'W':
+ if (opP->mode != MSCR || (opP->reg != DRP && opP->reg != SRP &&
+ opP->reg != CRP))
+ losing++;
+ break;
+
+ case 'X':
+ if (opP->mode != MSCR ||
+ (!(opP->reg >= BAD && opP->reg <= BAD+7) &&
+ !(opP->reg >= BAC && opP->reg <= BAC+7)))
+ losing++;
+ break;
+
+ case 'Y':
+ if (opP->reg != PSR)
+ losing++;
+ break;
+
+ case 'Z':
+ if (opP->reg != PCSR)
+ losing++;
+ break;
+#endif
+ default:
+ as_fatal("Internal error: Operand mode %c unknown",*s);
+ }
+ }
+ if(!losing)
+ break;
+ opcode=opcode->m_next;
+ if(!opcode) { /* Fell off the end */
+ the_ins.error="instruction/operands mismatch";
+ return;
+ }
+ losing=0;
+ }
+ the_ins.args=opcode->m_operands;
+ the_ins.numargs=opcode->m_opnum;
+ the_ins.numo=opcode->m_codenum;
+ the_ins.opcode[0]=getone(opcode);
+ the_ins.opcode[1]=gettwo(opcode);
+
+ for(s=the_ins.args,opP= &the_ins.operands[0];*s;s+=2,opP++) {
+ /* This switch is a doozy.
+ What the first step; its a big one! */
+ switch(s[0]) {
+
+ case '*':
+ case '~':
+ case '%':
+ case ';':
+ case '@':
+ case '!':
+ case '&':
+ case '$':
+ case '?':
+ case '/':
+#ifdef m68851
+ case '|':
+#endif
+ switch(opP->mode) {
+ case IMMED:
+ tmpreg=0x3c; /* 7.4 */
+ if(index("bwl",s[1])) nextword=get_num(opP->con1,80);
+ else nextword=nextword=get_num(opP->con1,0);
+ if(isvar(opP->con1))
+ add_fix(s[1],opP->con1,0);
+ switch(s[1]) {
+ case 'b':
+ if(!isbyte(nextword))
+ opP->error="operand out of range";
+ addword(nextword);
+ baseo=0;
+ break;
+ case 'w':
+ if(!isword(nextword))
+ opP->error="operand out of range";
+ addword(nextword);
+ baseo=0;
+ break;
+ case 'l':
+ addword(nextword>>16);
+ addword(nextword);
+ baseo=0;
+ break;
+
+ case 'f':
+ baseo=2;
+ outro=8;
+ break;
+ case 'F':
+ baseo=4;
+ outro=11;
+ break;
+ case 'x':
+ baseo=6;
+ outro=15;
+ break;
+ case 'p':
+ baseo=6;
+ outro= -1;
+ break;
+ default:
+ as_fatal("Internal error: Can't decode %c%c",*s,s[1]);
+ }
+ if(!baseo)
+ break;
+
+ /* We gotta put out some float */
+ if(seg(opP->con1)!=SEG_BIG) {
+ int_to_gen(nextword);
+ gen_to_words(words,baseo,(long int)outro);
+ for(wordp=words;baseo--;wordp++)
+ addword(*wordp);
+ break;
+ } /* Its BIG */
+ if(offs(opP->con1)>0) {
+ as_warn("Bignum assumed to be binary bit-pattern");
+ if(offs(opP->con1)>baseo) {
+ as_warn("Bignum too big for %c format; truncated",s[1]);
+ offs(opP->con1)=baseo;
+ }
+ baseo-=offs(opP->con1);
+ for(wordp=generic_bignum+offs(opP->con1)-1;offs(opP->con1)--;--wordp)
+ addword(*wordp);
+ while(baseo--)
+ addword(0);
+ break;
+ }
+ gen_to_words(words,baseo,(long int)outro);
+ for(wordp=words;baseo--;wordp++)
+ addword(*wordp);
+ break;
+ case DREG:
+ tmpreg=opP->reg-DATA; /* 0.dreg */
+ break;
+ case AREG:
+ tmpreg=0x08+opP->reg-ADDR; /* 1.areg */
+ break;
+ case AINDR:
+ tmpreg=0x10+opP->reg-ADDR; /* 2.areg */
+ break;
+ case ADEC:
+ tmpreg=0x20+opP->reg-ADDR; /* 4.areg */
+ break;
+ case AINC:
+ tmpreg=0x18+opP->reg-ADDR; /* 3.areg */
+ break;
+ case AOFF:
+
+ nextword=get_num(opP->con1,80);
+ /* Force into index mode. Hope this works */
+
+ /* We do the first bit for 32-bit displacements,
+ and the second bit for 16 bit ones. It is
+ possible that we should make the default be
+ WORD instead of LONG, but I think that'd
+ break GCC, so we put up with a little
+ inefficiency for the sake of working output.
+ */
+
+ if( !issword(nextword)
+ || ( isvar(opP->con1)
+ && ( ( opP->con1->e_siz==0
+ && flagseen['l']==0)
+ || opP->con1->e_siz==3))) {
+
+ if(opP->reg==PC)
+ tmpreg=0x3B; /* 7.3 */
+ else
+ tmpreg=0x30+opP->reg-ADDR; /* 6.areg */
+ if(isvar(opP->con1)) {
+ if(opP->reg==PC) {
+ add_frag(adds(opP->con1),
+ offs(opP->con1),
+ TAB(PCLEA,SZ_UNDEF));
+ break;
+ } else {
+ addword(0x0170);
+ add_fix('l',opP->con1,1);
+ }
+ } else
+ addword(0x0170);
+ addword(nextword>>16);
+ } else {
+ if(opP->reg==PC)
+ tmpreg=0x3A; /* 7.2 */
+ else
+ tmpreg=0x28+opP->reg-ADDR; /* 5.areg */
+
+ if(isvar(opP->con1)) {
+ if(opP->reg==PC) {
+ add_fix('w',opP->con1,1);
+ } else
+ add_fix('w',opP->con1,0);
+ }
+ }
+ addword(nextword);
+ break;
+ case AINDX:
+ case APODX:
+ case AMIND:
+ case APRDX:
+ nextword=0;
+ baseo=get_num(opP->con1,80);
+ outro=get_num(opP->con2,80);
+ /* Figure out the 'addressing mode' */
+ /* Also turn on the BASE_DISABLE bit, if needed */
+ if(opP->reg==PC || opP->reg==ZPC) {
+ tmpreg=0x3b; /* 7.3 */
+ if(opP->reg==ZPC)
+ nextword|=0x80;
+ } else if(opP->reg==FAIL) {
+ nextword|=0x80;
+ tmpreg=0x30; /* 6.garbage */
+ } else tmpreg=0x30+opP->reg-ADDR; /* 6.areg */
+
+ siz1= (opP->con1) ? opP->con1->e_siz : 0;
+ siz2= (opP->con2) ? opP->con2->e_siz : 0;
+
+ /* Index register stuff */
+ if(opP->ireg>=DATA+0 && opP->ireg<=ADDR+7) {
+ nextword|=(opP->ireg-DATA)<<12;
+
+ if(opP->isiz==0 || opP->isiz==3)
+ nextword|=0x800;
+ switch(opP->imul) {
+ case 1: break;
+ case 2: nextword|=0x200; break;
+ case 4: nextword|=0x400; break;
+ case 8: nextword|=0x600; break;
+ default: abort();
+ }
+ /* IF its simple,
+ GET US OUT OF HERE! */
+
+ /* Must be INDEX, with an index
+ register. Address register
+ cannot be ZERO-PC, and either
+ :b was forced, or we know
+ it will fit */
+ if( opP->mode==AINDX
+ && opP->reg!=FAIL
+ && opP->reg!=ZPC
+ && ( siz1==1
+ || ( issbyte(baseo)
+ && !isvar(opP->con1)))) {
+ nextword +=baseo&0xff;
+ addword(nextword);
+ if(isvar(opP->con1))
+ add_fix('B',opP->con1,0);
+ break;
+ }
+ } else
+ nextword|=0x40; /* No index reg */
+
+ /* It aint simple */
+ nextword|=0x100;
+ /* If the guy specified a width, we assume that
+ it is wide enough. Maybe it isn't. Ifso, we lose
+ */
+ switch(siz1) {
+ case 0:
+ if(isvar(opP->con1) || !issword(baseo)) {
+ siz1=3;
+ nextword|=0x30;
+ } else if(baseo==0)
+ nextword|=0x10;
+ else {
+ nextword|=0x20;
+ siz1=2;
+ }
+ break;
+ case 1:
+ as_warn("Byte dispacement won't work. Defaulting to :w");
+ case 2:
+ nextword|=0x20;
+ break;
+ case 3:
+ nextword|=0x30;
+ break;
+ }
+
+ /* Figure out innner displacement stuff */
+ if(opP->mode!=AINDX) {
+ switch(siz2) {
+ case 0:
+ if(isvar(opP->con2) || !issword(outro)) {
+ siz2=3;
+ nextword|=0x3;
+ } else if(outro==0)
+ nextword|=0x1;
+ else {
+ nextword|=0x2;
+ siz2=2;
+ }
+ break;
+ case 1:
+ as_warn("Byte dispacement won't work. Defaulting to :w");
+ case 2:
+ nextword|=0x2;
+ break;
+ case 3:
+ nextword|=0x3;
+ break;
+ }
+ if(opP->mode==APODX) nextword|=0x04;
+ else if(opP->mode==AMIND) nextword|=0x40;
+ }
+ addword(nextword);
+
+ if(isvar(opP->con1)) {
+ if(opP->reg==PC || opP->reg==ZPC) {
+ add_fix(siz1==3 ? 'l' : 'w',opP->con1,1);
+ opP->con1->e_exp.X_add_number+=6;
+ } else
+ add_fix(siz1==3 ? 'l' : 'w',opP->con1,0);
+ }
+ if(siz1==3)
+ addword(baseo>>16);
+ if(siz1)
+ addword(baseo);
+
+ if(isvar(opP->con2)) {
+ if(opP->reg==PC || opP->reg==ZPC) {
+ add_fix(siz2==3 ? 'l' : 'w',opP->con2,1);
+ opP->con1->e_exp.X_add_number+=6;
+ } else
+ add_fix(siz2==3 ? 'l' : 'w',opP->con2,0);
+ }
+ if(siz2==3)
+ addword(outro>>16);
+ if(siz2)
+ addword(outro);
+
+ break;
+
+ case ABSL:
+ nextword=get_num(opP->con1,80);
+ switch(opP->con1->e_siz) {
+ default:
+ as_warn("Unknown size for absolute reference");
+ case 0:
+ if(!isvar(opP->con1) && issword(offs(opP->con1))) {
+ tmpreg=0x38; /* 7.0 */
+ addword(nextword);
+ break;
+ }
+ /* Don't generate pc relative code
+ on 68010 and 68000 */
+ if(isvar(opP->con1) &&
+ !subs(opP->con1) &&
+ seg(opP->con1)==SEG_TEXT &&
+ now_seg==SEG_TEXT &&
+ flagseen['m']==0 &&
+ !index("~%&$?", s[0])) {
+ tmpreg=0x3A; /* 7.2 */
+ add_frag(adds(opP->con1),
+ offs(opP->con1),
+ TAB(PCREL,SZ_UNDEF));
+ break;
+ }
+ case 3: /* Fall through into long */
+ if(isvar(opP->con1))
+ add_fix('l',opP->con1,0);
+
+ tmpreg=0x39; /* 7.1 mode */
+ addword(nextword>>16);
+ addword(nextword);
+ break;
+
+ case 2: /* Word */
+ if(isvar(opP->con1))
+ add_fix('w',opP->con1,0);
+
+ tmpreg=0x38; /* 7.0 mode */
+ addword(nextword);
+ break;
+ }
+ break;
+ case MSCR:
+ default:
+ as_bad("unknown/incorrect operand");
+ /* abort(); */
+ }
+ install_gen_operand(s[1],tmpreg);
+ break;
+
+ case '#':
+ case '^':
+ switch(s[1]) { /* JF: I hate floating point! */
+ case 'j':
+ tmpreg=70;
+ break;
+ case '8':
+ tmpreg=20;
+ break;
+ case 'C':
+ tmpreg=50;
+ break;
+ case '3':
+ default:
+ tmpreg=80;
+ break;
+ }
+ tmpreg=get_num(opP->con1,tmpreg);
+ if(isvar(opP->con1))
+ add_fix(s[1],opP->con1,0);
+ switch(s[1]) {
+ case 'b': /* Danger: These do no check for
+ certain types of overflow.
+ user beware! */
+ if(!isbyte(tmpreg))
+ opP->error="out of range";
+ insop(tmpreg);
+ if(isvar(opP->con1))
+ the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2;
+ break;
+ case 'w':
+ if(!isword(tmpreg))
+ opP->error="out of range";
+ insop(tmpreg);
+ if(isvar(opP->con1))
+ the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2;
+ break;
+ case 'l':
+ insop(tmpreg); /* Because of the way insop works, we put these two out backwards */
+ insop(tmpreg>>16);
+ if(isvar(opP->con1))
+ the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2;
+ break;
+ case '3':
+ tmpreg&=0xFF;
+ case '8':
+ case 'C':
+ install_operand(s[1],tmpreg);
+ break;
+ default:
+ as_fatal("Internal error: Unknown mode #%c",s[1]);
+ }
+ break;
+
+ case '+':
+ case '-':
+ case 'A':
+ install_operand(s[1],opP->reg-ADDR);
+ break;
+
+ case 'B':
+ tmpreg=get_num(opP->con1,80);
+ switch(s[1]) {
+ case 'g':
+ if(opP->con1->e_siz) { /* Deal with fixed size stuff by hand */
+ switch(opP->con1->e_siz) {
+ case 1:
+ add_fix('b',opP->con1,1);
+ break;
+ case 2:
+ add_fix('w',opP->con1,1);
+ addword(0);
+ break;
+ case 3:
+ add_fix('l',opP->con1,1);
+ addword(0);
+ addword(0);
+ break;
+ default:
+ as_fatal("Bad size for expression %d",opP->con1->e_siz);
+ }
+ } else if(subs(opP->con1)) {
+ /* We can't relax it */
+ the_ins.opcode[the_ins.numo-1]|=0xff;
+ add_fix('l',opP->con1,1);
+ addword(0);
+ addword(0);
+ } else if(adds(opP->con1)) {
+ if (flagseen['m'] &&
+ (the_ins.opcode[0] >= 0x6200) &&
+ (the_ins.opcode[0] <= 0x6f00)) {
+ add_frag(adds(opP->con1),offs(opP->con1),TAB(BCC68000,SZ_UNDEF));
+ } else {
+ add_frag(adds(opP->con1),offs(opP->con1),TAB(BRANCH,SZ_UNDEF));
+ }
+ } else {
+ /* JF: This is the WRONG thing to do
+ add_frag((symbolS *)0,offs(opP->con1),TAB(BRANCH,BYTE)); */
+ the_ins.opcode[the_ins.numo-1]|=0xff;
+ offs(opP->con1)+=4;
+ add_fix('l',opP->con1,1);
+ addword(0);
+ addword(0);
+ }
+ break;
+ case 'w':
+ if(isvar(opP->con1)) {
+ /* check for DBcc instruction */
+ if ((the_ins.opcode[0] & 0xf0f8) ==0x50c8) {
+ /* size varies if patch */
+ /* needed for long form */
+ add_frag(adds(opP->con1),offs(opP->con1),TAB(DBCC,SZ_UNDEF));
+ break;
+ }
+
+ /* Don't ask! */
+ opP->con1->e_exp.X_add_number+=2;
+ add_fix('w',opP->con1,1);
+ }
+ addword(0);
+ break;
+ case 'c':
+ if(opP->con1->e_siz) {
+ switch(opP->con1->e_siz) {
+ case 2:
+ add_fix('w',opP->con1,1)
+ addword(0);
+ break;
+ case 3:
+ the_ins.opcode[the_ins.numo-1]|=0x40;
+ add_fix('l',opP->con1,1);
+ addword(0);
+ addword(0);
+ break;
+ default:
+ as_bad("Bad size for offset, must be word or long");
+ break;
+ }
+ } else if(subs(opP->con1)) {
+ add_fix('l',opP->con1,1);
+ add_frag((symbolS *)0,(long)0,TAB(FBRANCH,LONG));
+ } else if(adds(opP->con1)) {
+ add_frag(adds(opP->con1),offs(opP->con1),TAB(FBRANCH,SZ_UNDEF));
+ } else {
+ /* add_frag((symbolS *)0,offs(opP->con1),TAB(FBRANCH,SHORT)); */
+ the_ins.opcode[the_ins.numo-1]|=0x40;
+ add_fix('l',opP->con1,1);
+ addword(0);
+ addword(4);
+ }
+ break;
+ default:
+ as_fatal("Internal error: operand type B%c unknown",s[1]);
+ }
+ break;
+
+ case 'C': /* Ignore it */
+ break;
+
+ case 'd': /* JF this is a kludge */
+ if(opP->mode==AOFF) {
+ install_operand('s',opP->reg-ADDR);
+ } else {
+ char *tmpP;
+
+ tmpP=opP->con1->e_end-2;
+ opP->con1->e_beg++;
+ opP->con1->e_end-=4; /* point to the , */
+ baseo=m68k_reg_parse(&tmpP);
+ if(baseo<ADDR+0 || baseo>ADDR+7) {
+ as_bad("Unknown address reg, using A0");
+ baseo=0;
+ } else baseo-=ADDR;
+ install_operand('s',baseo);
+ }
+ tmpreg=get_num(opP->con1,80);
+ if(!issword(tmpreg)) {
+ as_warn("Expression out of range, using 0");
+ tmpreg=0;
+ }
+ addword(tmpreg);
+ break;
+
+ case 'D':
+ install_operand(s[1],opP->reg-DATA);
+ break;
+
+ case 'F':
+ install_operand(s[1],opP->reg-FPREG);
+ break;
+
+ case 'I':
+ tmpreg=1+opP->reg-COPNUM;
+ if(tmpreg==8)
+ tmpreg=0;
+ install_operand(s[1],tmpreg);
+ break;
+
+ case 'J': /* JF foo */
+ switch(opP->reg) {
+ case SFC:
+ tmpreg=0;
+ break;
+ case DFC:
+ tmpreg=0x001;
+ break;
+ case CACR:
+ tmpreg=0x002;
+ break;
+ case USP:
+ tmpreg=0x800;
+ break;
+ case VBR:
+ tmpreg=0x801;
+ break;
+ case CAAR:
+ tmpreg=0x802;
+ break;
+ case MSP:
+ tmpreg=0x803;
+ break;
+ case ISP:
+ tmpreg=0x804;
+ break;
+ default:
+ abort();
+ }
+ install_operand(s[1],tmpreg);
+ break;
+
+ case 'k':
+ tmpreg=get_num(opP->con1,55);
+ install_operand(s[1],tmpreg&0x7f);
+ break;
+
+ case 'l':
+ tmpreg=opP->reg;
+ if(s[1]=='w') {
+ if(tmpreg&0x7FF0000)
+ as_bad("Floating point register in register list");
+ insop(reverse_16_bits(tmpreg));
+ } else {
+ if(tmpreg&0x700FFFF)
+ as_bad("Wrong register in floating-point reglist");
+ install_operand(s[1],reverse_8_bits(tmpreg>>16));
+ }
+ break;
+
+ case 'L':
+ tmpreg=opP->reg;
+ if(s[1]=='w') {
+ if(tmpreg&0x7FF0000)
+ as_bad("Floating point register in register list");
+ insop(tmpreg);
+ } else if(s[1]=='8') {
+ if(tmpreg&0x0FFFFFF)
+ as_bad("incorrect register in reglist");
+ install_operand(s[1],tmpreg>>24);
+ } else {
+ if(tmpreg&0x700FFFF)
+ as_bad("wrong register in floating-point reglist");
+ else
+ install_operand(s[1],tmpreg>>16);
+ }
+ break;
+
+ case 'M':
+ install_operand(s[1],get_num(opP->con1,60));
+ break;
+
+ case 'O':
+ tmpreg= (opP->mode==DREG)
+ ? 0x20+opP->reg-DATA
+ : (get_num(opP->con1,40)&0x1F);
+ install_operand(s[1],tmpreg);
+ break;
+
+ case 'Q':
+ tmpreg=get_num(opP->con1,10);
+ if(tmpreg==8)
+ tmpreg=0;
+ install_operand(s[1],tmpreg);
+ break;
+
+ case 'R':
+ /* This depends on the fact that ADDR registers are
+ eight more than their corresponding DATA regs, so
+ the result will have the ADDR_REG bit set */
+ install_operand(s[1],opP->reg-DATA);
+ break;
+
+ case 's':
+ if(opP->reg==FPI) tmpreg=0x1;
+ else if(opP->reg==FPS) tmpreg=0x2;
+ else if(opP->reg==FPC) tmpreg=0x4;
+ else abort();
+ install_operand(s[1],tmpreg);
+ break;
+
+ case 'S': /* Ignore it */
+ break;
+
+ case 'T':
+ install_operand(s[1],get_num(opP->con1,30));
+ break;
+
+ case 'U': /* Ignore it */
+ break;
+
+#ifdef m68851
+ /* JF: These are out of order, I fear. */
+ case 'f':
+ switch (opP->reg) {
+ case SFC:
+ tmpreg=0;
+ break;
+ case DFC:
+ tmpreg=1;
+ break;
+ default:
+ abort();
+ }
+ install_operand(s[1],tmpreg);
+ break;
+
+ case 'P':
+ switch(opP->reg) {
+ case TC:
+ tmpreg=0;
+ break;
+ case CAL:
+ tmpreg=4;
+ break;
+ case VAL:
+ tmpreg=5;
+ break;
+ case SCC:
+ tmpreg=6;
+ break;
+ case AC:
+ tmpreg=7;
+ break;
+ default:
+ abort();
+ }
+ install_operand(s[1],tmpreg);
+ break;
+
+ case 'V':
+ if (opP->reg == VAL)
+ break;
+ abort();
+
+ case 'W':
+ switch(opP->reg) {
+
+ case DRP:
+ tmpreg=1;
+ break;
+ case SRP:
+ tmpreg=2;
+ break;
+ case CRP:
+ tmpreg=3;
+ break;
+ default:
+ abort();
+ }
+ install_operand(s[1],tmpreg);
+ break;
+
+ case 'X':
+ switch (opP->reg) {
+ case BAD: case BAD+1: case BAD+2: case BAD+3:
+ case BAD+4: case BAD+5: case BAD+6: case BAD+7:
+ tmpreg = (4 << 10) | ((opP->reg - BAD) << 2);
+ break;
+
+ case BAC: case BAC+1: case BAC+2: case BAC+3:
+ case BAC+4: case BAC+5: case BAC+6: case BAC+7:
+ tmpreg = (5 << 10) | ((opP->reg - BAC) << 2);
+ break;
+
+ default:
+ abort();
+ }
+ install_operand(s[1], tmpreg);
+ break;
+ case 'Y':
+ if (opP->reg == PSR)
+ break;
+ abort();
+
+ case 'Z':
+ if (opP->reg == PCSR)
+ break;
+ abort();
+#endif /* m68851 */
+ default:
+ as_fatal("Internal error: Operand type %c unknown",s[0]);
+ }
+ }
+ /* By the time whe get here (FINALLY) the_ins contains the complete
+ instruction, ready to be emitted. . . */
+}
+
+int
+get_regs(i,str,opP)
+struct m68k_op *opP;
+char *str;
+{
+ /* 26, 25, 24, 23-16, 15-8, 0-7 */
+ /* Low order 24 bits encoded fpc,fps,fpi,fp7-fp0,a7-a0,d7-d0 */
+ unsigned long int cur_regs = 0;
+ int reg1,
+ reg2;
+
+#define ADD_REG(x) { if(x==FPI) cur_regs|=(1<<24);\
+ else if(x==FPS) cur_regs|=(1<<25);\
+ else if(x==FPC) cur_regs|=(1<<26);\
+ else cur_regs|=(1<<(x-1)); }
+
+ reg1=i;
+ for(;;) {
+ if(*str=='/') {
+ ADD_REG(reg1);
+ str++;
+ } else if(*str=='-') {
+ str++;
+ reg2=m68k_reg_parse(&str);
+ if(reg2<DATA || reg2>=FPREG+8 || reg1==FPI || reg1==FPS || reg1==FPC) {
+ opP->error="unknown register in register list";
+ return FAIL;
+ }
+ while(reg1<=reg2) {
+ ADD_REG(reg1);
+ reg1++;
+ }
+ if(*str=='\0')
+ break;
+ } else if(*str=='\0') {
+ ADD_REG(reg1);
+ break;
+ } else {
+ opP->error="unknow character in register list";
+ return FAIL;
+ }
+/* DJA -- Bug Fix. Did't handle d1-d2/a1 until the following instruction was added */
+ if (*str=='/')
+ str ++;
+ reg1=m68k_reg_parse(&str);
+ if((reg1<DATA || reg1>=FPREG+8) && !(reg1==FPI || reg1==FPS || reg1==FPC)) {
+ opP->error="unknown register in register list";
+ return FAIL;
+ }
+ }
+ opP->reg=cur_regs;
+ return OK;
+}
+
+int
+reverse_16_bits(in)
+int in;
+{
+ int out=0;
+ int n;
+
+ static int mask[16] = {
+0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
+0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000
+ };
+ for(n=0;n<16;n++) {
+ if(in&mask[n])
+ out|=mask[15-n];
+ }
+ return out;
+}
+
+int
+reverse_8_bits(in)
+int in;
+{
+ int out=0;
+ int n;
+
+ static int mask[8] = {
+0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
+ };
+
+ for(n=0;n<8;n++) {
+ if(in&mask[n])
+ out|=mask[7-n];
+ }
+ return out;
+}
+
+void
+install_operand(mode,val)
+int mode;
+int val;
+{
+ switch(mode) {
+ case 's':
+ the_ins.opcode[0]|=val & 0xFF; /* JF FF is for M kludge */
+ break;
+ case 'd':
+ the_ins.opcode[0]|=val<<9;
+ break;
+ case '1':
+ the_ins.opcode[1]|=val<<12;
+ break;
+ case '2':
+ the_ins.opcode[1]|=val<<6;
+ break;
+ case '3':
+ the_ins.opcode[1]|=val;
+ break;
+ case '4':
+ the_ins.opcode[2]|=val<<12;
+ break;
+ case '5':
+ the_ins.opcode[2]|=val<<6;
+ break;
+ case '6':
+ /* DANGER! This is a hack to force cas2l and cas2w cmds
+ to be three words long! */
+ the_ins.numo++;
+ the_ins.opcode[2]|=val;
+ break;
+ case '7':
+ the_ins.opcode[1]|=val<<7;
+ break;
+ case '8':
+ the_ins.opcode[1]|=val<<10;
+ break;
+#ifdef m68851
+ case '9':
+ the_ins.opcode[1]|=val<<5;
+ break;
+#endif
+
+ case 't':
+ the_ins.opcode[1]|=(val<<10)|(val<<7);
+ break;
+ case 'D':
+ the_ins.opcode[1]|=(val<<12)|val;
+ break;
+ case 'g':
+ the_ins.opcode[0]|=val=0xff;
+ break;
+ case 'i':
+ the_ins.opcode[0]|=val<<9;
+ break;
+ case 'C':
+ the_ins.opcode[1]|=val;
+ break;
+ case 'j':
+ the_ins.opcode[1]|=val;
+ the_ins.numo++; /* What a hack */
+ break;
+ case 'k':
+ the_ins.opcode[1]|=val<<4;
+ break;
+ case 'b':
+ case 'w':
+ case 'l':
+ break;
+ case 'c':
+ default:
+ abort();
+ }
+}
+
+void
+install_gen_operand(mode,val)
+int mode;
+int val;
+{
+ switch(mode) {
+ case 's':
+ the_ins.opcode[0]|=val;
+ break;
+ case 'd':
+ /* This is a kludge!!! */
+ the_ins.opcode[0]|=(val&0x07)<<9|(val&0x38)<<3;
+ break;
+ case 'b':
+ case 'w':
+ case 'l':
+ case 'f':
+ case 'F':
+ case 'x':
+ case 'p':
+ the_ins.opcode[0]|=val;
+ break;
+ /* more stuff goes here */
+ default:
+ abort();
+ }
+}
+
+char *
+crack_operand(str,opP)
+register char *str;
+register struct m68k_op *opP;
+{
+ register int parens;
+ register int c;
+ register char *beg_str;
+
+ if(!str) {
+ return str;
+ }
+ beg_str=str;
+ for(parens=0;*str && (parens>0 || notend(str));str++) {
+ if(*str=='(') parens++;
+ else if(*str==')') {
+ if(!parens) { /* ERROR */
+ opP->error="Extra )";
+ return str;
+ }
+ --parens;
+ }
+ }
+ if(!*str && parens) { /* ERROR */
+ opP->error="Missing )";
+ return str;
+ }
+ c= *str;
+ *str='\0';
+ if(m68k_ip_op(beg_str,opP)==FAIL) {
+ *str=c;
+ return str;
+ }
+ *str=c;
+ if(c=='}')
+ c= *++str; /* JF bitfield hack */
+ if(c) {
+ c= *++str;
+ if(!c)
+ as_bad("Missing operand");
+ }
+ return str;
+}
+
+/* See the comment up above where the #define notend(... is */
+#if 0
+notend(s)
+char *s;
+{
+ if(*s==',') return 0;
+ if(*s=='{' || *s=='}')
+ return 0;
+ if(*s!=':') return 1;
+ /* This kludge here is for the division cmd, which is a kludge */
+ if(index("aAdD#",s[1])) return 0;
+ return 1;
+}
+#endif
+
+/* This is the guts of the machine-dependent assembler. STR points to a
+ machine dependent instruction. This funciton is supposed to emit
+ the frags/bytes it assembles to.
+ */
+void
+md_assemble(str)
+char *str;
+{
+ char *er;
+ short *fromP;
+ char *toP;
+ int m,n;
+ char *to_beg_P;
+ int shorts_this_frag;
+
+ bzero((char *)(&the_ins),sizeof(the_ins)); /* JF for paranoia sake */
+ m68_ip(str);
+ er=the_ins.error;
+ if(!er) {
+ for(n=the_ins.numargs;n;--n)
+ if(the_ins.operands[n].error) {
+ er=the_ins.operands[n].error;
+ break;
+ }
+ }
+ if(er) {
+ as_bad("\"%s\" -- Statement '%s' ignored",er,str);
+ return;
+ }
+
+ if(the_ins.nfrag==0) { /* No frag hacking involved; just put it out */
+ toP=frag_more(2*the_ins.numo);
+ fromP= &the_ins.opcode[0];
+ for(m=the_ins.numo;m;--m) {
+ md_number_to_chars(toP,(long)(*fromP),2);
+ toP+=2;
+ fromP++;
+ }
+ /* put out symbol-dependent info */
+ for(m=0;m<the_ins.nrel;m++) {
+ switch(the_ins.reloc[m].wid) {
+ case 'B':
+ n=1;
+ break;
+ case 'b':
+ n=1;
+ break;
+ case '3':
+ n=2;
+ break;
+ case 'w':
+ n=2;
+ break;
+ case 'l':
+ n=4;
+ break;
+ default:
+ as_fatal("Don't know how to figure width of %c in md_assemble()",the_ins.reloc[m].wid);
+ }
+
+ fix_new(frag_now,
+ (toP-frag_now->fr_literal)-the_ins.numo*2+the_ins.reloc[m].n,
+ n,
+ the_ins.reloc[m].add,
+ the_ins.reloc[m].sub,
+ the_ins.reloc[m].off,
+ the_ins.reloc[m].pcrel);
+ }
+ return;
+ }
+
+ /* There's some frag hacking */
+ for(n=0,fromP= &the_ins.opcode[0];n<the_ins.nfrag;n++) {
+ int wid;
+
+ if(n==0) wid=2*the_ins.fragb[n].fragoff;
+ else wid=2*(the_ins.numo-the_ins.fragb[n-1].fragoff);
+ toP=frag_more(wid);
+ to_beg_P=toP;
+ shorts_this_frag=0;
+ for(m=wid/2;m;--m) {
+ md_number_to_chars(toP,(long)(*fromP),2);
+ toP+=2;
+ fromP++;
+ shorts_this_frag++;
+ }
+ for(m=0;m<the_ins.nrel;m++) {
+ if((the_ins.reloc[m].n)>= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */) {
+ the_ins.reloc[m].n-= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */;
+ break;
+ }
+ wid=the_ins.reloc[m].wid;
+ if(wid==0)
+ continue;
+ the_ins.reloc[m].wid=0;
+ wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000;
+
+ fix_new(frag_now,
+ (toP-frag_now->fr_literal)-the_ins.numo*2+the_ins.reloc[m].n,
+ wid,
+ the_ins.reloc[m].add,
+ the_ins.reloc[m].sub,
+ the_ins.reloc[m].off,
+ the_ins.reloc[m].pcrel);
+ }
+ know(the_ins.fragb[n].fadd);
+ (void)frag_var(rs_machine_dependent,10,0,(relax_substateT)(the_ins.fragb[n].fragty),
+ the_ins.fragb[n].fadd,the_ins.fragb[n].foff,to_beg_P);
+ }
+ n=(the_ins.numo-the_ins.fragb[n-1].fragoff);
+ shorts_this_frag=0;
+ if(n) {
+ toP=frag_more(n*sizeof(short));
+ while(n--) {
+ md_number_to_chars(toP,(long)(*fromP),2);
+ toP+=2;
+ fromP++;
+ shorts_this_frag++;
+ }
+ }
+ for(m=0;m<the_ins.nrel;m++) {
+ int wid;
+
+ wid=the_ins.reloc[m].wid;
+ if(wid==0)
+ continue;
+ the_ins.reloc[m].wid=0;
+ wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000;
+
+ fix_new(frag_now,
+ (the_ins.reloc[m].n + toP-frag_now->fr_literal)-/* the_ins.numo */ shorts_this_frag*2,
+ wid,
+ the_ins.reloc[m].add,
+ the_ins.reloc[m].sub,
+ the_ins.reloc[m].off,
+ the_ins.reloc[m].pcrel);
+ }
+}
+
+/* This function is called once, at assembler startup time. This should
+ set up all the tables, etc that the MD part of the assembler needs
+ */
+void
+md_begin()
+{
+/*
+ * md_begin -- set up hash tables with 68000 instructions.
+ * similar to what the vax assembler does. ---phr
+ */
+ /* RMS claims the thing to do is take the m68k-opcode.h table, and make
+ a copy of it at runtime, adding in the information we want but isn't
+ there. I think it'd be better to have an awk script hack the table
+ at compile time. Or even just xstr the table and use it as-is. But
+ my lord ghod hath spoken, so we do it this way. Excuse the ugly var
+ names. */
+
+ register struct m68k_opcode *ins;
+ register struct m68_incant *hack,
+ *slak;
+ register char *retval = 0; /* empty string, or error msg text */
+ register int i;
+ register char c;
+
+ if ((op_hash = hash_new()) == NULL)
+ as_fatal("Virtual memory exhausted");
+
+ obstack_begin(&robyn,4000);
+ for (ins = m68k_opcodes; ins < endop; ins++) {
+ hack=slak=(struct m68_incant *)obstack_alloc(&robyn,sizeof(struct m68_incant));
+ do {
+ slak->m_operands=ins->args;
+ slak->m_opnum=strlen(slak->m_operands)/2;
+ slak->m_opcode=ins->opcode;
+ /* This is kludgey */
+ slak->m_codenum=((ins->match)&0xffffL) ? 2 : 1;
+ if((ins+1)!=endop && !strcmp(ins->name,(ins+1)->name)) {
+ slak->m_next=(struct m68_incant *)
+obstack_alloc(&robyn,sizeof(struct m68_incant));
+ ins++;
+ } else
+ slak->m_next=0;
+ slak=slak->m_next;
+ } while(slak);
+
+ retval = hash_insert (op_hash, ins->name,(char *)hack);
+ /* Didn't his mommy tell him about null pointers? */
+ if(retval && *retval)
+ as_fatal("Internal Error: Can't hash %s: %s",ins->name,retval);
+ }
+
+ for (i = 0; i < sizeof(mklower_table) ; i++)
+ mklower_table[i] = (isupper(c = (char) i)) ? tolower(c) : c;
+
+ for (i = 0 ; i < sizeof(notend_table) ; i++) {
+ notend_table[i] = 0;
+ alt_notend_table[i] = 0;
+ }
+ notend_table[','] = 1;
+ notend_table['{'] = 1;
+ notend_table['}'] = 1;
+ alt_notend_table['a'] = 1;
+ alt_notend_table['A'] = 1;
+ alt_notend_table['d'] = 1;
+ alt_notend_table['D'] = 1;
+ alt_notend_table['#'] = 1;
+ alt_notend_table['f'] = 1;
+ alt_notend_table['F'] = 1;
+#ifdef REGISTER_PREFIX
+ alt_notend_table[REGISTER_PREFIX] = 1;
+#endif
+}
+
+#if 0
+#define notend(s) ((*s == ',' || *s == '}' || *s == '{' \
+ || (*s == ':' && index("aAdD#", s[1]))) \
+ ? 0 : 1)
+#endif
+
+/* This funciton is called once, before the assembler exits. It is
+ supposed to do any final cleanup for this part of the assembler.
+ */
+void
+md_end()
+{
+}
+
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+char *
+md_atof(type,litP,sizeP)
+char type;
+char *litP;
+int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+ char *atof_ieee();
+
+ switch(type) {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP=0;
+ return "Bad call to MD_ATOF()";
+ }
+ t=atof_ieee(input_line_pointer,type,words);
+ if(t)
+ input_line_pointer=t;
+
+ *sizeP=prec * sizeof(LITTLENUM_TYPE);
+ for(wordP=words;prec--;) {
+ md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
+ litP+=sizeof(LITTLENUM_TYPE);
+ }
+ return ""; /* Someone should teach Dean about null pointers */
+}
+
+/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
+ for use in the a.out file, and stores them in the array pointed to by buf.
+ This knows about the endian-ness of the target machine and does
+ THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
+ 2 (short) and 4 (long) Floating numbers are put out as a series of
+ LITTLENUMS (shorts, here at least)
+ */
+void
+md_number_to_chars(buf,val,n)
+char *buf;
+long val;
+int n;
+{
+ switch(n) {
+ case 1:
+ *buf++=val;
+ break;
+ case 2:
+ *buf++=(val>>8);
+ *buf++=val;
+ break;
+ case 4:
+ *buf++=(val>>24);
+ *buf++=(val>>16);
+ *buf++=(val>>8);
+ *buf++=val;
+ break;
+ default:
+ abort();
+ }
+}
+
+void
+md_number_to_imm(buf,val,n)
+char *buf;
+long val;
+int n;
+{
+ switch(n) {
+ case 1:
+ *buf++=val;
+ break;
+ case 2:
+ *buf++=(val>>8);
+ *buf++=val;
+ break;
+ case 4:
+ *buf++=(val>>24);
+ *buf++=(val>>16);
+ *buf++=(val>>8);
+ *buf++=val;
+ break;
+ default:
+ abort();
+ }
+}
+
+void
+md_number_to_disp(buf,val,n)
+char *buf;
+long val;
+int n;
+{
+ abort();
+}
+
+void
+md_number_to_field(buf,val,fix)
+char *buf;
+long val;
+void *fix;
+{
+ abort();
+}
+
+
+/* *fragP has been relaxed to its final size, and now needs to have
+ the bytes inside it modified to conform to the new size There is UGLY
+ MAGIC here. ..
+ */
+void
+md_convert_frag(fragP)
+register fragS *fragP;
+{
+ long disp;
+ long ext;
+
+ /* Address in gas core of the place to store the displacement. */
+ register char *buffer_address = fragP -> fr_fix + fragP -> fr_literal;
+ /* Address in object code of the displacement. */
+ register int object_address = fragP -> fr_fix + fragP -> fr_address;
+
+ know(fragP->fr_symbol);
+
+ /* The displacement of the address, from current location. */
+ disp = (fragP->fr_symbol->sy_value + fragP->fr_offset) - object_address;
+
+ switch(fragP->fr_subtype) {
+ case TAB(BCC68000,BYTE):
+ case TAB(BRANCH,BYTE):
+ know(issbyte(disp));
+ if(disp==0)
+ as_bad("short branch with zero offset: use :w");
+ fragP->fr_opcode[1]=disp;
+ ext=0;
+ break;
+ case TAB(DBCC,SHORT):
+ know(issword(disp));
+ ext=2;
+ break;
+ case TAB(BCC68000,SHORT):
+ case TAB(BRANCH,SHORT):
+ know(issword(disp));
+ fragP->fr_opcode[1]=0x00;
+ ext=2;
+ break;
+ case TAB(BRANCH,LONG):
+ if(flagseen['m']) {
+ if(fragP->fr_opcode[0]==0x61) {
+ fragP->fr_opcode[0]= 0x4E;
+ fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */
+ subseg_change(SEG_TEXT, 0);
+ fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset, 0);
+ fragP->fr_fix+=4;
+ ext=0;
+ } else if(fragP->fr_opcode[0]==0x60) {
+ fragP->fr_opcode[0]= 0x4E;
+ fragP->fr_opcode[1]= 0xF9; /* JMP with ABSL LONG offset */
+ subseg_change(SEG_TEXT, 0);
+ fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset,0);
+ fragP->fr_fix+=4;
+ ext=0;
+ }else {
+ as_bad("Long branch offset not supported.");
+ }
+ } else {
+ fragP->fr_opcode[1]=0xff;
+ ext=4;
+ }
+ break;
+ case TAB(BCC68000,LONG):
+ /* only Bcc 68000 instructions can come here */
+ /* change bcc into b!cc/jmp absl long */
+ fragP->fr_opcode[0] ^= 0x01; /* invert bcc */
+ fragP->fr_opcode[1] = 0x6; /* branch offset = 6 */
+
+ /* JF: these used to be fr_opcode[2,3], but they may be in a
+ different frag, in which case refering to them is a no-no.
+ Only fr_opcode[0,1] are guaranteed to work. */
+ *buffer_address++ = 0x4e; /* put in jmp long (0x4ef9) */
+ *buffer_address++ = 0xf9;
+ fragP->fr_fix += 2; /* account for jmp instruction */
+ subseg_change(SEG_TEXT,0);
+ fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
+ fragP->fr_offset,0);
+ fragP->fr_fix += 4;
+ ext=0;
+ break;
+ case TAB(DBCC,LONG):
+ /* only DBcc 68000 instructions can come here */
+ /* change dbcc into dbcc/jmp absl long */
+ /* JF: these used to be fr_opcode[2-7], but that's wrong */
+ *buffer_address++ = 0x00; /* branch offset = 4 */
+ *buffer_address++ = 0x04;
+ *buffer_address++ = 0x60; /* put in bra pc+6 */
+ *buffer_address++ = 0x06;
+ *buffer_address++ = 0x4e; /* put in jmp long (0x4ef9) */
+ *buffer_address++ = 0xf9;
+
+ fragP->fr_fix += 6; /* account for bra/jmp instructions */
+ subseg_change(SEG_TEXT,0);
+ fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
+ fragP->fr_offset,0);
+ fragP->fr_fix += 4;
+ ext=0;
+ break;
+ case TAB(FBRANCH,SHORT):
+ know((fragP->fr_opcode[1]&0x40)==0);
+ ext=2;
+ break;
+ case TAB(FBRANCH,LONG):
+ fragP->fr_opcode[1]|=0x40; /* Turn on LONG bit */
+ ext=4;
+ break;
+ case TAB(PCREL,SHORT):
+ ext=2;
+ break;
+ case TAB(PCREL,LONG):
+ /* The thing to do here is force it to ABSOLUTE LONG, since
+ PCREL is really trying to shorten an ABSOLUTE address anyway */
+ /* JF FOO This code has not been tested */
+ subseg_change(SEG_TEXT,0);
+ fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset, 0);
+ if((fragP->fr_opcode[1] & 0x3F) != 0x3A)
+ as_bad("Internal error (long PC-relative operand) for insn 0x%04lx at 0x%lx",
+ fragP->fr_opcode[0],fragP->fr_address);
+ fragP->fr_opcode[1]&= ~0x3F;
+ fragP->fr_opcode[1]|=0x39; /* Mode 7.1 */
+ fragP->fr_fix+=4;
+ /* md_number_to_chars(buffer_address,
+ (long)(fragP->fr_symbol->sy_value + fragP->fr_offset),
+ 4); */
+ ext=0;
+ break;
+ case TAB(PCLEA,SHORT):
+ subseg_change(SEG_TEXT,0);
+ fix_new(fragP,(int)(fragP->fr_fix),2,fragP->fr_symbol,(symbolS *)0,fragP->fr_offset,1);
+ fragP->fr_opcode[1] &= ~0x3F;
+ fragP->fr_opcode[1] |= 0x3A;
+ ext=2;
+ break;
+ case TAB(PCLEA,LONG):
+ subseg_change(SEG_TEXT,0);
+ fix_new(fragP,(int)(fragP->fr_fix)+2,4,fragP->fr_symbol,(symbolS *)0,fragP->fr_offset+2,1);
+ *buffer_address++ = 0x01;
+ *buffer_address++ = 0x70;
+ fragP->fr_fix+=2;
+ /* buffer_address+=2; */
+ ext=4;
+ break;
+
+ }
+ if(ext) {
+ md_number_to_chars(buffer_address,(long)disp,(int)ext);
+ fragP->fr_fix+=ext;
+ }
+}
+
+/* Force truly undefined symbols to their maximum size, and generally set up
+ the frag list to be relaxed
+ */
+int
+md_estimate_size_before_relax(fragP,segtype)
+register fragS *fragP;
+int segtype;
+{
+ int old_fix;
+ register char *buffer_address = fragP -> fr_fix + fragP -> fr_literal;
+
+ old_fix=fragP->fr_fix;
+
+ /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */
+ switch(fragP->fr_subtype) {
+ case TAB(BRANCH,SZ_UNDEF):
+ if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
+ fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE);
+ break;
+ } else if(flagseen['m']) {
+ if(fragP->fr_opcode[0]==0x61) {
+ if(flagseen['l']) {
+ fragP->fr_opcode[0]= 0x4E;
+ fragP->fr_opcode[1]= 0xB8; /* JBSR with ABSL WORD offset */
+ subseg_change(SEG_TEXT, 0);
+ fix_new(fragP, fragP->fr_fix, 2,
+ fragP->fr_symbol, 0, fragP->fr_offset, 0);
+ fragP->fr_fix+=2;
+ } else {
+ fragP->fr_opcode[0]= 0x4E;
+ fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */
+ subseg_change(SEG_TEXT, 0);
+ fix_new(fragP, fragP->fr_fix, 4,
+ fragP->fr_symbol, 0, fragP->fr_offset, 0);
+ fragP->fr_fix+=4;
+ }
+ frag_wane(fragP);
+ } else if(fragP->fr_opcode[0]==0x60) {
+ if(flagseen['l']) {
+ fragP->fr_opcode[0]= 0x4E;
+ fragP->fr_opcode[1]= 0xF8; /* JMP with ABSL WORD offset */
+ subseg_change(SEG_TEXT, 0);
+ fix_new(fragP, fragP->fr_fix, 2,
+ fragP->fr_symbol, 0, fragP->fr_offset, 0);
+ fragP->fr_fix+=2;
+ } else {
+ fragP->fr_opcode[0]= 0x4E;
+ fragP->fr_opcode[1]= 0xF9; /* JMP with ABSL LONG offset */
+ subseg_change(SEG_TEXT, 0);
+ fix_new(fragP, fragP->fr_fix, 4,
+ fragP->fr_symbol, 0, fragP->fr_offset, 0);
+ fragP->fr_fix+=4;
+ }
+ frag_wane(fragP);
+ } else {
+ as_warn("Long branch offset to extern symbol not supported.");
+ }
+ } else if(flagseen['l']) { /* Symbol is still undefined. Make it simple */
+ fix_new(fragP,(int)(fragP->fr_fix),2,fragP->fr_symbol,
+ (symbolS *)0,fragP->fr_offset + 2,1);
+ fragP->fr_fix+=2;
+ fragP->fr_opcode[1]=0x00;
+ frag_wane(fragP);
+ } else {
+ fix_new(fragP,(int)(fragP->fr_fix),4,fragP->fr_symbol,
+ (symbolS *)0,fragP->fr_offset + 4,1);
+ fragP->fr_fix+=4;
+ fragP->fr_opcode[1]=0xff;
+ frag_wane(fragP);
+ break;
+ }
+ break;
+
+ case TAB(FBRANCH,SZ_UNDEF):
+ if((fragP->fr_symbol->sy_type&N_TYPE)==segtype || flagseen['l']) {
+ fragP->fr_subtype=TAB(FBRANCH,SHORT);
+ fragP->fr_var+=2;
+ } else {
+ fragP->fr_subtype=TAB(FBRANCH,LONG);
+ fragP->fr_var+=4;
+ }
+ break;
+
+ case TAB(PCREL,SZ_UNDEF):
+ if((fragP->fr_symbol->sy_type&N_TYPE)==segtype || flagseen['l']) {
+ fragP->fr_subtype=TAB(PCREL,SHORT);
+ fragP->fr_var+=2;
+ } else {
+ fragP->fr_subtype=TAB(PCREL,LONG);
+ fragP->fr_var+=4;
+ }
+ break;
+
+ case TAB(BCC68000,SZ_UNDEF):
+ if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
+ fragP->fr_subtype=TAB(BCC68000,BYTE);
+ break;
+ }
+ /* only Bcc 68000 instructions can come here */
+ /* change bcc into b!cc/jmp absl long */
+ fragP->fr_opcode[0] ^= 0x01; /* invert bcc */
+ if(flagseen['l']) {
+ fragP->fr_opcode[1] = 0x04; /* branch offset = 6 */
+ /* JF: these were fr_opcode[2,3] */
+ buffer_address[0] = 0x4e; /* put in jmp long (0x4ef9) */
+ buffer_address[1] = 0xf8;
+ fragP->fr_fix += 2; /* account for jmp instruction */
+ subseg_change(SEG_TEXT,0);
+ fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0,
+ fragP->fr_offset,0);
+ fragP->fr_fix += 2;
+ } else {
+ fragP->fr_opcode[1] = 0x06; /* branch offset = 6 */
+ /* JF: these were fr_opcode[2,3] */
+ buffer_address[2] = 0x4e; /* put in jmp long (0x4ef9) */
+ buffer_address[3] = 0xf9;
+ fragP->fr_fix += 2; /* account for jmp instruction */
+ subseg_change(SEG_TEXT,0);
+ fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
+ fragP->fr_offset,0);
+ fragP->fr_fix += 4;
+ }
+ frag_wane(fragP);
+ break;
+
+ case TAB(DBCC,SZ_UNDEF):
+ if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
+ fragP->fr_subtype=TAB(DBCC,SHORT);
+ fragP->fr_var+=2;
+ break;
+ }
+ /* only DBcc 68000 instructions can come here */
+ /* change dbcc into dbcc/jmp absl long */
+ /* JF: these used to be fr_opcode[2-4], which is wrong. */
+ buffer_address[0] = 0x00; /* branch offset = 4 */
+ buffer_address[1] = 0x04;
+ buffer_address[2] = 0x60; /* put in bra pc + ... */
+ if(flagseen['l']) {
+ /* JF: these were fr_opcode[5-7] */
+ buffer_address[3] = 0x04; /* plus 4 */
+ buffer_address[4] = 0x4e;/* Put in Jump Word */
+ buffer_address[5] = 0xf8;
+ fragP->fr_fix += 6; /* account for bra/jmp instruction */
+ subseg_change(SEG_TEXT,0);
+ fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0,
+ fragP->fr_offset,0);
+ fragP->fr_fix+=2;
+ } else {
+ /* JF: these were fr_opcode[5-7] */
+ buffer_address[3] = 0x06; /* Plus 6 */
+ buffer_address[4] = 0x4e; /* put in jmp long (0x4ef9) */
+ buffer_address[5] = 0xf9;
+ fragP->fr_fix += 6; /* account for bra/jmp instruction */
+ subseg_change(SEG_TEXT,0);
+ fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
+ fragP->fr_offset,0);
+ fragP->fr_fix += 4;
+ }
+ frag_wane(fragP);
+ break;
+
+ case TAB(PCLEA,SZ_UNDEF):
+ if((fragP->fr_symbol->sy_type&N_TYPE)==segtype || flagseen['l']) {
+ fragP->fr_subtype=TAB(PCLEA,SHORT);
+ fragP->fr_var+=2;
+ } else {
+ fragP->fr_subtype=TAB(PCLEA,LONG);
+ fragP->fr_var+=6;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* now that SZ_UNDEF are taken care of, check others */
+ switch(fragP->fr_subtype) {
+ case TAB(BCC68000,BYTE):
+ case TAB(BRANCH,BYTE):
+ /* We can't do a short jump to the next instruction,
+ so we force word mode. */
+ if(fragP->fr_symbol && fragP->fr_symbol->sy_value==0 &&
+ fragP->fr_symbol->sy_frag==fragP->fr_next) {
+ fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT);
+ fragP->fr_var+=2;
+ }
+ break;
+ default:
+ break;
+ }
+ return fragP->fr_var + fragP->fr_fix - old_fix;
+}
+
+/* the bit-field entries in the relocation_info struct plays hell
+ with the byte-order problems of cross-assembly. So as a hack,
+ I added this mach. dependent ri twiddler. Ugly, but it gets
+ you there. -KWK */
+/* on m68k: first 4 bytes are normal unsigned long, next three bytes
+are symbolnum, most sig. byte first. Last byte is broken up with
+bit 7 as pcrel, bits 6 & 5 as length, bit 4 as pcrel, and the lower
+nibble as nuthin. (on Sun 3 at least) */
+void
+md_ri_to_chars(ri_p, ri)
+ struct relocation_info *ri_p, ri;
+{
+ unsigned char the_bytes[8];
+
+ /* this is easy */
+ md_number_to_chars(the_bytes, ri.r_address, sizeof(ri.r_address));
+ /* now the fun stuff */
+ the_bytes[4] = (ri.r_symbolnum >> 16) & 0x0ff;
+ the_bytes[5] = (ri.r_symbolnum >> 8) & 0x0ff;
+ the_bytes[6] = ri.r_symbolnum & 0x0ff;
+ the_bytes[7] = (((ri.r_pcrel << 7) & 0x80) | ((ri.r_length << 5) & 0x60) |
+ ((ri.r_extern << 4) & 0x10));
+ /* now put it back where you found it */
+ bcopy (the_bytes, (char *)ri_p, sizeof(struct relocation_info));
+}
+
+#ifndef WORKING_DOT_WORD
+const int md_short_jump_size = 4;
+const int md_long_jump_size = 6;
+
+void
+md_create_short_jump(ptr,from_addr,to_addr,frag,to_symbol)
+char *ptr;
+long from_addr,
+ to_addr;
+fragS *frag;
+symbolS *to_symbol;
+{
+ long offset;
+
+ offset = to_addr - (from_addr+2);
+
+ md_number_to_chars(ptr ,(long)0x6000,2);
+ md_number_to_chars(ptr+2,(long)offset,2);
+}
+
+void
+md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol)
+char *ptr;
+long from_addr,
+ to_addr;
+fragS *frag;
+symbolS *to_symbol;
+{
+ long offset;
+
+ if(flagseen['m']) {
+ offset=to_addr-to_symbol->sy_value;
+ md_number_to_chars(ptr ,(long)0x4EF9,2);
+ md_number_to_chars(ptr+2,(long)offset,4);
+ fix_new(frag,(ptr+2)-frag->fr_literal,4,to_symbol,(symbolS *)0,(long int)0,0);
+ } else {
+ offset=to_addr - (from_addr+2);
+ md_number_to_chars(ptr ,(long)0x60ff,2);
+ md_number_to_chars(ptr+2,(long)offset,4);
+ }
+}
+
+#endif
+/* Different values of OK tell what its OK to return. Things that aren't OK are an error (what a shock, no?)
+
+ 0: Everything is OK
+ 10: Absolute 1:8 only
+ 20: Absolute 0:7 only
+ 30: absolute 0:15 only
+ 40: Absolute 0:31 only
+ 50: absolute 0:127 only
+ 55: absolute -64:63 only
+ 60: absolute -128:127 only
+ 70: absolute 0:4095 only
+ 80: No bignums
+
+*/
+int
+get_num(exp,ok)
+struct m68k_exp *exp;
+int ok;
+{
+#ifdef TEST2
+ long l = 0;
+
+ if(!exp->e_beg)
+ return 0;
+ if(*exp->e_beg=='0') {
+ if(exp->e_beg[1]=='x')
+ sscanf(exp->e_beg+2,"%x",&l);
+ else
+ sscanf(exp->e_beg+1,"%O",&l);
+ return l;
+ }
+ return atol(exp->e_beg);
+#else
+ char *save_in;
+ char c_save;
+
+ if(!exp) {
+ /* Can't do anything */
+ return 0;
+ }
+ if(!exp->e_beg || !exp->e_end) {
+ seg(exp)=SEG_ABSOLUTE;
+ adds(exp)=0;
+ subs(exp)=0;
+ offs(exp)= (ok==10) ? 1 : 0;
+ as_warn("Null expression defaults to %ld",offs(exp));
+ return 0;
+ }
+
+ exp->e_siz=0;
+ if(/* ok!=80 && */exp->e_end[-1]==':' && (exp->e_end-exp->e_beg)>=2) {
+ switch(exp->e_end[0]) {
+ case 's':
+ case 'S':
+ case 'b':
+ case 'B':
+ exp->e_siz=1;
+ break;
+ case 'w':
+ case 'W':
+ exp->e_siz=2;
+ break;
+ case 'l':
+ case 'L':
+ exp->e_siz=3;
+ break;
+ default:
+ as_bad("Unknown size for expression \"%c\"",exp->e_end[0]);
+ }
+ exp->e_end-=2;
+ }
+ c_save=exp->e_end[1];
+ exp->e_end[1]='\0';
+ save_in=input_line_pointer;
+ input_line_pointer=exp->e_beg;
+ switch(expression(&(exp->e_exp))) {
+ case SEG_PASS1:
+ seg(exp)=SEG_ABSOLUTE;
+ adds(exp)=0;
+ subs(exp)=0;
+ offs(exp)= (ok==10) ? 1 : 0;
+ as_warn("Unknown expression: '%s' defaulting to %d",exp->e_beg,offs(exp));
+ break;
+
+ case SEG_NONE:
+ /* Do the same thing the VAX asm does */
+ seg(exp)=SEG_ABSOLUTE;
+ adds(exp)=0;
+ subs(exp)=0;
+ offs(exp)=0;
+ if(ok==10) {
+ as_warn("expression out of range: defaulting to 1");
+ offs(exp)=1;
+ }
+ break;
+ case SEG_ABSOLUTE:
+ switch(ok) {
+ case 10:
+ if(offs(exp)<1 || offs(exp)>8) {
+ as_warn("expression out of range: defaulting to 1");
+ offs(exp)=1;
+ }
+ break;
+ case 20:
+ if(offs(exp)<0 || offs(exp)>7)
+ goto outrange;
+ break;
+ case 30:
+ if(offs(exp)<0 || offs(exp)>15)
+ goto outrange;
+ break;
+ case 40:
+ if(offs(exp)<0 || offs(exp)>32)
+ goto outrange;
+ break;
+ case 50:
+ if(offs(exp)<0 || offs(exp)>127)
+ goto outrange;
+ break;
+ case 55:
+ if(offs(exp)<-64 || offs(exp)>63)
+ goto outrange;
+ break;
+ case 60:
+ if(offs(exp)<-128 || offs(exp)>127)
+ goto outrange;
+ break;
+ case 70:
+ if(offs(exp)<0 || offs(exp)>4095) {
+ outrange:
+ as_warn("expression out of range: defaulting to 0");
+ offs(exp)=0;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case SEG_TEXT:
+ case SEG_DATA:
+ case SEG_BSS:
+ case SEG_UNKNOWN:
+ case SEG_DIFFERENCE:
+ if(ok>=10 && ok<=70) {
+ seg(exp)=SEG_ABSOLUTE;
+ adds(exp)=0;
+ subs(exp)=0;
+ offs(exp)= (ok==10) ? 1 : 0;
+ as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp));
+ }
+ break;
+ case SEG_BIG:
+ if(ok==80 && offs(exp)<0) { /* HACK! Turn it into a long */
+ LITTLENUM_TYPE words[6];
+
+ gen_to_words(words,2,8L);/* These numbers are magic! */
+ seg(exp)=SEG_ABSOLUTE;
+ adds(exp)=0;
+ subs(exp)=0;
+ offs(exp)=words[1]|(words[0]<<16);
+ } else if(ok!=0) {
+ seg(exp)=SEG_ABSOLUTE;
+ adds(exp)=0;
+ subs(exp)=0;
+ offs(exp)= (ok==10) ? 1 : 0;
+ as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp));
+ }
+ break;
+ default:
+ abort();
+ }
+ if(input_line_pointer!=exp->e_end+1)
+ as_bad("Ignoring junk after expression");
+ exp->e_end[1]=c_save;
+ input_line_pointer=save_in;
+ if(exp->e_siz) {
+ switch(exp->e_siz) {
+ case 1:
+ if(!isbyte(offs(exp)))
+ as_warn("expression doesn't fit in BYTE");
+ break;
+ case 2:
+ if(!isword(offs(exp)))
+ as_warn("expression doesn't fit in WORD");
+ break;
+ }
+ }
+ return offs(exp);
+#endif
+}
+
+/* These are the back-ends for the various machine dependent pseudo-ops. */
+void demand_empty_rest_of_line(); /* Hate those extra verbose names */
+
+void
+s_data1()
+{
+ subseg_new(SEG_DATA,1);
+ demand_empty_rest_of_line();
+}
+
+void
+s_data2()
+{
+ subseg_new(SEG_DATA,2);
+ demand_empty_rest_of_line();
+}
+
+void
+s_even()
+{
+ register int temp;
+ register long int temp_fill;
+
+ temp = 1; /* JF should be 2? */
+ temp_fill = get_absolute_expression ();
+ if ( ! need_pass_2 ) /* Never make frag if expect extra pass. */
+ frag_align (temp, (int)temp_fill);
+ demand_empty_rest_of_line();
+}
+
+void
+s_proc()
+{
+ demand_empty_rest_of_line();
+}
+
+/* s_space is defined in read.c .skip is simply an alias to it. */
+
+int
+md_parse_option(argP,cntP,vecP)
+char **argP;
+int *cntP;
+char ***vecP;
+{
+ switch(**argP) {
+ case 'l': /* -l means keep external to 2 bit offset
+ rather than 16 bit one */
+ break;
+
+ case 'm':
+ /* Gas almost ignores this option! */
+ (*argP)++;
+ if(**argP=='c')
+ (*argP)++;
+ if(!strcmp(*argP,"68000"))
+ flagseen['m']=2;
+ else if(!strcmp(*argP,"68010")) {
+#ifdef M_SUN
+ omagic= 1<<16|OMAGIC;
+#endif
+ flagseen['m']=1;
+ } else if(!strcmp(*argP,"68020"))
+ flagseen['m']=0;
+ else
+ as_warn("Unknown -m option ignored");
+ while(**argP)
+ (*argP)++;
+ break;
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+
+#ifdef TEST2
+
+/* TEST2: Test md_assemble() */
+/* Warning, this routine probably doesn't work anymore */
+
+main()
+{
+ struct m68_it the_ins;
+ char buf[120];
+ char *cp;
+ int n;
+
+ m68_ip_begin();
+ for(;;) {
+ if(!gets(buf) || !*buf)
+ break;
+ if(buf[0]=='|' || buf[1]=='.')
+ continue;
+ for(cp=buf;*cp;cp++)
+ if(*cp=='\t')
+ *cp=' ';
+ if(is_label(buf))
+ continue;
+ bzero(&the_ins,sizeof(the_ins));
+ m68_ip(&the_ins,buf);
+ if(the_ins.error) {
+ printf("Error %s in %s\n",the_ins.error,buf);
+ } else {
+ printf("Opcode(%d.%s): ",the_ins.numo,the_ins.args);
+ for(n=0;n<the_ins.numo;n++)
+ printf(" 0x%x",the_ins.opcode[n]&0xffff);
+ printf(" ");
+ print_the_insn(&the_ins.opcode[0],stdout);
+ (void)putchar('\n');
+ }
+ for(n=0;n<strlen(the_ins.args)/2;n++) {
+ if(the_ins.operands[n].error) {
+ printf("op%d Error %s in %s\n",n,the_ins.operands[n].error,buf);
+ continue;
+ }
+ printf("mode %d, reg %d, ",the_ins.operands[n].mode,the_ins.operands[n].reg);
+ if(the_ins.operands[n].b_const)
+ printf("Constant: '%.*s', ",1+the_ins.operands[n].e_const-the_ins.operands[n].b_const,the_ins.operands[n].b_const);
+ printf("ireg %d, isiz %d, imul %d, ",the_ins.operands[n].ireg,the_ins.operands[n].isiz,the_ins.operands[n].imul);
+ if(the_ins.operands[n].b_iadd)
+ printf("Iadd: '%.*s',",1+the_ins.operands[n].e_iadd-the_ins.operands[n].b_iadd,the_ins.operands[n].b_iadd);
+ (void)putchar('\n');
+ }
+ }
+ m68_ip_end();
+ return 0;
+}
+
+is_label(str)
+char *str;
+{
+ while(*str==' ')
+ str++;
+ while(*str && *str!=' ')
+ str++;
+ if(str[-1]==':' || str[1]=='=')
+ return 1;
+ return 0;
+}
+
+#endif
+
+/* Possible states for relaxation:
+
+0 0 branch offset byte (bra, etc)
+0 1 word
+0 2 long
+
+1 0 indexed offsets byte a0@(32,d4:w:1) etc
+1 1 word
+1 2 long
+
+2 0 two-offset index word-word a0@(32,d4)@(45) etc
+2 1 word-long
+2 2 long-word
+2 3 long-long
+
+*/
+
+
+
+#ifdef DONTDEF
+abort()
+{
+ printf("ABORT!\n");
+ exit(12);
+}
+
+char *index(s,c)
+char *s;
+{
+ while(*s!=c) {
+ if(!*s) return 0;
+ s++;
+ }
+ return s;
+}
+
+bzero(s,n)
+char *s;
+{
+ while(n--)
+ *s++=0;
+}
+
+print_frags()
+{
+ fragS *fragP;
+ extern fragS *text_frag_root;
+
+ for(fragP=text_frag_root;fragP;fragP=fragP->fr_next) {
+ printf("addr %lu next 0x%x fix %ld var %ld symbol 0x%x offset %ld\n",
+ fragP->fr_address,fragP->fr_next,fragP->fr_fix,fragP->fr_var,fragP->fr_symbol,fragP->fr_offset);
+ printf("opcode 0x%x type %d subtype %d\n\n",fragP->fr_opcode,fragP->fr_type,fragP->fr_subtype);
+ }
+ fflush(stdout);
+ return 0;
+}
+#endif
+
+#ifdef DONTDEF
+/*VARARGS1*/
+panic(format,args)
+char *format;
+{
+ fputs("Internal error:",stderr);
+ _doprnt(format,&args,stderr);
+ (void)putc('\n',stderr);
+ as_where();
+ abort();
+}
+#endif
diff --git a/gnu/usr.bin/gas/config/m68k.h b/gnu/usr.bin/gas/config/m68k.h
new file mode 100644
index 00000000000..2e4709e5ff6
--- /dev/null
+++ b/gnu/usr.bin/gas/config/m68k.h
@@ -0,0 +1,20 @@
+/* m-generic.h Generic machine-specific header file.
+ Copyright (C) 1987 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#define M_GENERIC 1
diff --git a/gnu/usr.bin/gas/config/ns32k-opcode.h b/gnu/usr.bin/gas/config/ns32k-opcode.h
new file mode 100644
index 00000000000..c851c34f0e6
--- /dev/null
+++ b/gnu/usr.bin/gas/config/ns32k-opcode.h
@@ -0,0 +1,434 @@
+/* ns32k-opcode.h -- Opcode table for National Semi 32k processor
+ Copyright (C) 1987 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+#ifdef SEQUENT_COMPATABILITY
+#define DEF_MODEC 20
+#define DEF_MODEL 21
+#endif
+
+#ifndef DEF_MODEC
+#define DEF_MODEC 20
+#endif
+
+#ifndef DEF_MODEL
+#define DEF_MODEL 20
+#endif
+/*
+ After deciding the instruction entry (via hash.c) the instruction parser
+ will try to match the operands after the instruction to the required set
+ given in the entry operandfield. Every operand will result in a change in
+ the opcode or the addition of data to the opcode.
+ The operands in the source instruction are checked for inconsistent
+ semantics.
+
+ F : 32 bit float general form
+ L : 64 bit float "
+ B : byte "
+ W : word "
+ D : double-word "
+ Q : quad-word "
+ A : double-word gen-address-form ie no regs allowed
+ d : displacement
+ b : displacement - pc relative addressing acb
+ p : displacement - pc relative addressing br bcond bsr cxp
+ q : quick
+ i : immediate (8 bits)
+ This is not a standard ns32k operandtype, it is used to build
+ instructions like svc arg1,arg2
+ Svc is the instruction SuperVisorCall and is sometimes used to
+ call OS-routines from usermode. Some args might be handy!
+ r : register number (3 bits)
+ O : setcfg instruction optionslist
+ C : cinv instruction optionslist
+ S : stringinstruction optionslist
+ U : registerlist save,enter
+ u : registerlist restore,exit
+ M : mmu register
+ P : cpu register
+ g : 3:rd operand of inss or exts instruction
+ G : 4:th operand of inss or exts instruction
+ Those operands are encoded in the same byte.
+ This byte is placed last in the instruction.
+ f : operand of sfsr
+ H : sequent-hack for bsr (Warning)
+
+column 1 instructions
+ 2 number of bits in opcode.
+ 3 number of bits in opcode explicitly
+ determined by the instruction type.
+ 4 opcodeseed, the number we build our opcode
+ from.
+ 5 operandtypes, used by operandparser.
+ 6 size in bytes of immediate
+*/
+struct ns32k_opcode {
+ char *name;
+ unsigned char opcode_id_size; /* not used by the assembler */
+ unsigned char opcode_size;
+ unsigned long opcode_seed;
+ char *operands;
+ unsigned char im_size; /* not used by dissassembler */
+ char *default_args; /* default to those args when none given */
+ char default_modec; /* default to this addr-mode when ambigous
+ ie when the argument of a general addr-mode
+ is a plain constant */
+ char default_model; /* is a plain label */
+};
+
+struct ns32k_opcode ns32k_opcodes[]=
+{
+ { "absf", 14,24, 0x35be, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "absl", 14,24, 0x34be, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "absb", 14,24, 0x304e, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "absw", 14,24, 0x314e, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "absd", 14,24, 0x334e, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "acbb", 7,16, 0x4c, "2B1q3p", 1, "", DEF_MODEC,DEF_MODEL },
+ { "acbw", 7,16, 0x4d, "2W1q3p", 2, "", DEF_MODEC,DEF_MODEL },
+ { "acbd", 7,16, 0x4f, "2D1q3p", 4, "", DEF_MODEC,DEF_MODEL },
+ { "addf", 14,24, 0x01be, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "addl", 14,24, 0x00be, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "addb", 6,16, 0x00, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "addw", 6,16, 0x01, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "addd", 6,16, 0x03, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "addcb", 6,16, 0x10, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "addcw", 6,16, 0x11, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "addcd", 6,16, 0x13, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "addpb", 14,24, 0x3c4e, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "addpw", 14,24, 0x3d4e, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "addpd", 14,24, 0x3f4e, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "addqb", 7,16, 0x0c, "2B1q", 1, "", DEF_MODEC,DEF_MODEL },
+ { "addqw", 7,16, 0x0d, "2W1q", 2, "", DEF_MODEC,DEF_MODEL },
+ { "addqd", 7,16, 0x0f, "2D1q", 4, "", DEF_MODEC,DEF_MODEL },
+ { "addr", 6,16, 0x27, "1A2D", 4, "", 21,21 },
+ { "adjspb", 11,16, 0x057c, "1B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "adjspw", 11,16, 0x057d, "1W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "adjspd", 11,16, 0x057f, "1D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "andb", 6,16, 0x28, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "andw", 6,16, 0x29, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "andd", 6,16, 0x2b, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "ashb", 14,24, 0x044e, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "ashw", 14,24, 0x054e, "1B2W", 1, "", DEF_MODEC,DEF_MODEL },
+ { "ashd", 14,24, 0x074e, "1B2D", 1, "", DEF_MODEC,DEF_MODEL },
+ { "beq", 8,8, 0x0a, "1p", 0, "", 21,21 },
+ { "bne", 8,8, 0x1a, "1p", 0, "", 21,21 },
+ { "bcs", 8,8, 0x2a, "1p", 0, "", 21,21 },
+ { "bcc", 8,8, 0x3a, "1p", 0, "", 21,21 },
+ { "bhi", 8,8, 0x4a, "1p", 0, "", 21,21 },
+ { "bls", 8,8, 0x5a, "1p", 0, "", 21,21 },
+ { "bgt", 8,8, 0x6a, "1p", 0, "", 21,21 },
+ { "ble", 8,8, 0x7a, "1p", 0, "", 21,21 },
+ { "bfs", 8,8, 0x8a, "1p", 0, "", 21,21 },
+ { "bfc", 8,8, 0x9a, "1p", 0, "", 21,21 },
+ { "blo", 8,8, 0xaa, "1p", 0, "", 21,21 },
+ { "bhs", 8,8, 0xba, "1p", 0, "", 21,21 },
+ { "blt", 8,8, 0xca, "1p", 0, "", 21,21 },
+ { "bge", 8,8, 0xda, "1p", 0, "", 21,21 },
+ { "but", 8,8, 0xea, "1p", 0, "", 21,21 },
+ { "buf", 8,8, 0xfa, "1p", 0, "", 21,21 },
+ { "bicb", 6,16, 0x08, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "bicw", 6,16, 0x09, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "bicd", 6,16, 0x0b, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "bicpsrb", 11,16, 0x17c, "1B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "bicpsrw", 11,16, 0x17d, "1W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "bispsrb", 11,16, 0x37c, "1B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "bispsrw", 11,16, 0x37d, "1W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "bpt", 8,8, 0xf2, "", 0, "", DEF_MODEC,DEF_MODEL },
+ { "br", 8,8, 0xea, "1p", 0, "", 21,21 },
+#ifdef SEQUENT_COMPATABILITY
+ { "bsr", 8,8, 0x02, "1H", 0, "", 21,21 },
+#else
+ { "bsr", 8,8, 0x02, "1p", 0, "", 21,21 },
+#endif
+ { "caseb", 11,16, 0x77c, "1B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "casew", 11,16, 0x77d, "1W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "cased", 11,16, 0x77f, "1D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cbitb", 14,24, 0x084e, "1B2D", 1, "", DEF_MODEC,DEF_MODEL },
+ { "cbitw", 14,24, 0x094e, "1W2D", 2, "", DEF_MODEC,DEF_MODEL },
+ { "cbitd", 14,24, 0x0b4e, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cbitib", 14,24, 0x0c4e, "1B2D", 1, "", DEF_MODEC,DEF_MODEL },
+ { "cbitiw", 14,24, 0x0d4e, "1W2D", 2, "", DEF_MODEC,DEF_MODEL },
+ { "cbitid", 14,24, 0x0f4e, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "checkb", 11,24, 0x0ee, "2A3B1r", 1, "", DEF_MODEC,DEF_MODEL },
+ { "checkw", 11,24, 0x1ee, "2A3W1r", 2, "", DEF_MODEC,DEF_MODEL },
+ { "checkd", 11,24, 0x3ee, "2A3D1r", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cinv", 14,24, 0x271e, "2D1C", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cmpf", 14,24, 0x09be, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cmpl", 14,24, 0x08be, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "cmpb", 6,16, 0x04, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "cmpw", 6,16, 0x05, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "cmpd", 6,16, 0x07, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cmpmb", 14,24, 0x04ce, "1A2A3b", 1, "", DEF_MODEC,DEF_MODEL },
+ { "cmpmw", 14,24, 0x05ce, "1A2A3b", 2, "", DEF_MODEC,DEF_MODEL },
+ { "cmpmd", 14,24, 0x07ce, "1A2A3b", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cmpqb", 7,16, 0x1c, "2B1q", 1, "", DEF_MODEC,DEF_MODEL },
+ { "cmpqw", 7,16, 0x1d, "2W1q", 2, "", DEF_MODEC,DEF_MODEL },
+ { "cmpqd", 7,16, 0x1f, "2D1q", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cmpsb", 16,24, 0x040e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "cmpsw", 16,24, 0x050e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "cmpsd", 16,24, 0x070e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "cmpst", 16,24, 0x840e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "comb", 14,24, 0x344e, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "comw", 14,24, 0x354e, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "comd", 14,24, 0x374e, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cvtp", 11,24, 0x036e, "2A3D1r", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cxp", 8,8, 0x22, "1p", 0, "", 21,21 },
+ { "cxpd", 11,16, 0x07f, "1A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "deib", 14,24, 0x2cce, "1B2W", 1, "", DEF_MODEC,DEF_MODEL },
+ { "deiw", 14,24, 0x2dce, "1W2D", 2, "", DEF_MODEC,DEF_MODEL },
+ { "deid", 14,24, 0x2fce, "1D2Q", 4, "", DEF_MODEC,DEF_MODEL },
+ { "dia", 8,8, 0xc2, "", 1, "", DEF_MODEC,DEF_MODEL },
+ { "divf", 14,24, 0x21be, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "divl", 14,24, 0x20be, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "divb", 14,24, 0x3cce, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "divw", 14,24, 0x3dce, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "divd", 14,24, 0x3fce, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "enter", 8,8, 0x82, "1U2d", 0, "", DEF_MODEC,DEF_MODEL },
+ { "exit", 8,8, 0x92, "1u", 0, "", DEF_MODEC,DEF_MODEL },
+ { "extb", 11,24, 0x02e, "2D3B1r4d", 1, "", DEF_MODEC,DEF_MODEL },
+ { "extw", 11,24, 0x12e, "2D3W1r4d", 2, "", DEF_MODEC,DEF_MODEL },
+ { "extd", 11,24, 0x32e, "2D3D1r4d", 4, "", DEF_MODEC,DEF_MODEL },
+ { "extsb", 14,24, 0x0cce, "1D2B3g4G", 1, "", DEF_MODEC,DEF_MODEL },
+ { "extsw", 14,24, 0x0dce, "1D2W3g4G", 2, "", DEF_MODEC,DEF_MODEL },
+ { "extsd", 14,24, 0x0fce, "1D2D3g4G", 4, "", DEF_MODEC,DEF_MODEL },
+ { "ffsb", 14,24, 0x046e, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "ffsw", 14,24, 0x056e, "1W2B", 2, "", DEF_MODEC,DEF_MODEL },
+ { "ffsd", 14,24, 0x076e, "1D2B", 4, "", DEF_MODEC,DEF_MODEL },
+ { "flag", 8,8, 0xd2, "", 0, "", DEF_MODEC,DEF_MODEL },
+ { "floorfb", 14,24, 0x3c3e, "1F2B", 4, "", DEF_MODEC,DEF_MODEL },
+ { "floorfw", 14,24, 0x3d3e, "1F2W", 4, "", DEF_MODEC,DEF_MODEL },
+ { "floorfd", 14,24, 0x3f3e, "1F2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "floorlb", 14,24, 0x383e, "1L2B", 8, "", DEF_MODEC,DEF_MODEL },
+ { "floorlw", 14,24, 0x393e, "1L2W", 8, "", DEF_MODEC,DEF_MODEL },
+ { "floorld", 14,24, 0x3b3e, "1L2D", 8, "", DEF_MODEC,DEF_MODEL },
+ { "ibitb", 14,24, 0x384e, "1B2D", 1, "", DEF_MODEC,DEF_MODEL },
+ { "ibitw", 14,24, 0x394e, "1W2D", 2, "", DEF_MODEC,DEF_MODEL },
+ { "ibitd", 14,24, 0x3b4e, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "indexb", 11,24, 0x42e, "2B3B1r", 1, "", DEF_MODEC,DEF_MODEL },
+ { "indexw", 11,24, 0x52e, "2W3W1r", 2, "", DEF_MODEC,DEF_MODEL },
+ { "indexd", 11,24, 0x72e, "2D3D1r", 4, "", DEF_MODEC,DEF_MODEL },
+ { "insb", 11,24, 0x0ae, "2B3B1r4d", 1, "", DEF_MODEC,DEF_MODEL },
+ { "insw", 11,24, 0x1ae, "2W3W1r4d", 2, "", DEF_MODEC,DEF_MODEL },
+ { "insd", 11,24, 0x3ae, "2D3D1r4d", 4, "", DEF_MODEC,DEF_MODEL },
+ { "inssb", 14,24, 0x08ce, "1B2D3g4G", 1, "", DEF_MODEC,DEF_MODEL },
+ { "inssw", 14,24, 0x09ce, "1W2D3g4G", 2, "", DEF_MODEC,DEF_MODEL },
+ { "inssd", 14,24, 0x0bce, "1D2D3g4G", 4, "", DEF_MODEC,DEF_MODEL },
+ { "jsr", 11,16, 0x67f, "1A", 4, "", 21,21 },
+ { "jump", 11,16, 0x27f, "1A", 4, "", 21,21 },
+ { "lfsr", 19,24, 0x00f3e,"1D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "lmr", 15,24, 0x0b1e, "2D1M", 4, "", DEF_MODEC,DEF_MODEL },
+ { "lprb", 7,16, 0x6c, "2B1P", 1, "", DEF_MODEC,DEF_MODEL },
+ { "lprw", 7,16, 0x6d, "2W1P", 2, "", DEF_MODEC,DEF_MODEL },
+ { "lprd", 7,16, 0x6f, "2D1P", 4, "", DEF_MODEC,DEF_MODEL },
+ { "lshb", 14,24, 0x144e, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "lshw", 14,24, 0x154e, "1B2W", 1, "", DEF_MODEC,DEF_MODEL },
+ { "lshd", 14,24, 0x174e, "1B2D", 1, "", DEF_MODEC,DEF_MODEL },
+ { "meib", 14,24, 0x24ce, "1B2W", 1, "", DEF_MODEC,DEF_MODEL },
+ { "meiw", 14,24, 0x25ce, "1W2D", 2, "", DEF_MODEC,DEF_MODEL },
+ { "meid", 14,24, 0x27ce, "1D2Q", 4, "", DEF_MODEC,DEF_MODEL },
+ { "modb", 14,24, 0x38ce, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "modw", 14,24, 0x39ce, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "modd", 14,24, 0x3bce, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movf", 14,24, 0x05be, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movl", 14,24, 0x04be, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "movb", 6,16, 0x14, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movw", 6,16, 0x15, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movd", 6,16, 0x17, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movbf", 14,24, 0x043e, "1B2F", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movwf", 14,24, 0x053e, "1W2F", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movdf", 14,24, 0x073e, "1D2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movbl", 14,24, 0x003e, "1B2L", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movwl", 14,24, 0x013e, "1W2L", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movdl", 14,24, 0x033e, "1D2L", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movfl", 14,24, 0x1b3e, "1F2L", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movlf", 14,24, 0x163e, "1L2F", 8, "", DEF_MODEC,DEF_MODEL },
+ { "movmb", 14,24, 0x00ce, "1A2A3b", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movmw", 14,24, 0x01ce, "1A2A3b", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movmd", 14,24, 0x03ce, "1A2A3b", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movqb", 7,16, 0x5c, "2B1q", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movqw", 7,16, 0x5d, "2B1q", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movqd", 7,16, 0x5f, "2B1q", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movsb", 16,24, 0x000e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "movsw", 16,24, 0x010e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "movsd", 16,24, 0x030e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "movst", 16,24, 0x800e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "movsub", 14,24, 0x0cae, "1A2A", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movsuw", 14,24, 0x0dae, "1A2A", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movsud", 14,24, 0x0fae, "1A2A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movusb", 14,24, 0x1cae, "1A2A", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movusw", 14,24, 0x1dae, "1A2A", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movusd", 14,24, 0x1fae, "1A2A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movxbd", 14,24, 0x1cce, "1B2D", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movxwd", 14,24, 0x1dce, "1W2D", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movxbw", 14,24, 0x10ce, "1B2W", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movzbd", 14,24, 0x18ce, "1B2D", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movzwd", 14,24, 0x19ce, "1W2D", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movzbw", 14,24, 0x14ce, "1B2W", 1, "", DEF_MODEC,DEF_MODEL },
+ { "mulf", 14,24, 0x31be, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "mull", 14,24, 0x30be, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "mulb", 14,24, 0x20ce, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "mulw", 14,24, 0x21ce, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "muld", 14,24, 0x23ce, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "negf", 14,24, 0x15be, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "negl", 14,24, 0x14be, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "negb", 14,24, 0x204e, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "negw", 14,24, 0x214e, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "negd", 14,24, 0x234e, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "nop", 8,8, 0xa2, "", 0, "", DEF_MODEC,DEF_MODEL },
+ { "notb", 14,24, 0x244e, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "notw", 14,24, 0x254e, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "notd", 14,24, 0x274e, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "orb", 6,16, 0x18, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "orw", 6,16, 0x19, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "ord", 6,16, 0x1b, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "quob", 14,24, 0x30ce, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "quow", 14,24, 0x31ce, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "quod", 14,24, 0x33ce, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "rdval", 19,24, 0x0031e,"1A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "remb", 14,24, 0x34ce, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "remw", 14,24, 0x35ce, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "remd", 14,24, 0x37ce, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "restore", 8,8, 0x72, "1u", 0, "", DEF_MODEC,DEF_MODEL },
+ { "ret", 8,8, 0x12, "1d", 0, "", DEF_MODEC,DEF_MODEL },
+ { "reti", 8,8, 0x52, "", 0, "", DEF_MODEC,DEF_MODEL },
+ { "rett", 8,8, 0x42, "1d", 0, "", DEF_MODEC,DEF_MODEL },
+ { "rotb", 14,24, 0x004e, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "rotw", 14,24, 0x014e, "1B2W", 1, "", DEF_MODEC,DEF_MODEL },
+ { "rotd", 14,24, 0x034e, "1B2D", 1, "", DEF_MODEC,DEF_MODEL },
+ { "roundfb", 14,24, 0x243e, "1F2B", 4, "", DEF_MODEC,DEF_MODEL },
+ { "roundfw", 14,24, 0x253e, "1F2W", 4, "", DEF_MODEC,DEF_MODEL },
+ { "roundfd", 14,24, 0x273e, "1F2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "roundlb", 14,24, 0x203e, "1L2B", 8, "", DEF_MODEC,DEF_MODEL },
+ { "roundlw", 14,24, 0x213e, "1L2W", 8, "", DEF_MODEC,DEF_MODEL },
+ { "roundld", 14,24, 0x233e, "1L2D", 8, "", DEF_MODEC,DEF_MODEL },
+ { "rxp", 8,8, 0x32, "1d", 0, "", DEF_MODEC,DEF_MODEL },
+ { "seqb", 11,16, 0x3c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "seqw", 11,16, 0x3d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "seqd", 11,16, 0x3f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sneb", 11,16, 0xbc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "snew", 11,16, 0xbd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sned", 11,16, 0xbf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "scsb", 11,16, 0x13c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "scsw", 11,16, 0x13d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "scsd", 11,16, 0x13f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sccb", 11,16, 0x1bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sccw", 11,16, 0x1bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sccd", 11,16, 0x1bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "shib", 11,16, 0x23c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "shiw", 11,16, 0x23d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "shid", 11,16, 0x23f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slsb", 11,16, 0x2bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slsw", 11,16, 0x2bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slsd", 11,16, 0x2bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sgtb", 11,16, 0x33c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sgtw", 11,16, 0x33d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sgtd", 11,16, 0x33f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sleb", 11,16, 0x3bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slew", 11,16, 0x3bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sled", 11,16, 0x3bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfsb", 11,16, 0x43c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfsw", 11,16, 0x43d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfsd", 11,16, 0x43f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfcb", 11,16, 0x4bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfcw", 11,16, 0x4bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfcd", 11,16, 0x4bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slob", 11,16, 0x53c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slow", 11,16, 0x53d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slod", 11,16, 0x53f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "shsb", 11,16, 0x5bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "shsw", 11,16, 0x5bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "shsd", 11,16, 0x5bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sltb", 11,16, 0x63c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sltw", 11,16, 0x63d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sltd", 11,16, 0x63f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sgeb", 11,16, 0x6bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sgew", 11,16, 0x6bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sged", 11,16, 0x6bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sutb", 11,16, 0x73c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sutw", 11,16, 0x73d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sutd", 11,16, 0x73f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sufb", 11,16, 0x7bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sufw", 11,16, 0x7bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sufd", 11,16, 0x7bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "save", 8,8, 0x62, "1U", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sbitb", 14,24, 0x184e, "1B2A", 1, "", DEF_MODEC,DEF_MODEL },
+ { "sbitw", 14,24, 0x194e, "1W2A", 2, "", DEF_MODEC,DEF_MODEL },
+ { "sbitd", 14,24, 0x1b4e, "1D2A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "sbitib", 14,24, 0x1c4e, "1B2A", 1, "", DEF_MODEC,DEF_MODEL },
+ { "sbitiw", 14,24, 0x1d4e, "1W2A", 2, "", DEF_MODEC,DEF_MODEL },
+ { "sbitid", 14,24, 0x1f4e, "1D2A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "setcfg", 15,24, 0x0b0e, "1O", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfsr", 14,24, 0x373e, "1f", 0, "", DEF_MODEC,DEF_MODEL },
+ { "skpsb", 16,24, 0x0c0e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "skpsw", 16,24, 0x0d0e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "skpsd", 16,24, 0x0f0e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "skpst", 16,24, 0x8c0e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "smr", 15,24, 0x0f1e, "2D1M", 4, "", DEF_MODEC,DEF_MODEL },
+ { "sprb", 7,16, 0x2c, "2B1P", 1, "", DEF_MODEC,DEF_MODEL },
+ { "sprw", 7,16, 0x2d, "2W1P", 2, "", DEF_MODEC,DEF_MODEL },
+ { "sprd", 7,16, 0x2f, "2D1P", 4, "", DEF_MODEC,DEF_MODEL },
+ { "subf", 14,24, 0x11be, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "subl", 14,24, 0x10be, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "subb", 6,16, 0x20, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "subw", 6,16, 0x21, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "subd", 6,16, 0x23, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "subcb", 6,16, 0x30, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "subcw", 6,16, 0x31, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "subcd", 6,16, 0x33, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "subpb", 14,24, 0x2c4e, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "subpw", 14,24, 0x2d4e, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "subpd", 14,24, 0x2f4e, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+#ifdef NS32K_SVC_IMMED_OPERANDS
+ { "svc", 8,8, 0xe2, "2i1i", 1, "", DEF_MODEC,DEF_MODEL }, /* not really, but unix uses it */
+#else
+ { "svc", 8,8, 0xe2, "", 0, "", DEF_MODEC,DEF_MODEL },
+#endif
+ { "tbitb", 6,16, 0x34, "1B2A", 1, "", DEF_MODEC,DEF_MODEL },
+ { "tbitw", 6,16, 0x35, "1W2A", 2, "", DEF_MODEC,DEF_MODEL },
+ { "tbitd", 6,16, 0x37, "1D2A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "truncfb", 14,24, 0x2c3e, "1F2B", 4, "", DEF_MODEC,DEF_MODEL },
+ { "truncfw", 14,24, 0x2d3e, "1F2W", 4, "", DEF_MODEC,DEF_MODEL },
+ { "truncfd", 14,24, 0x2f3e, "1F2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "trunclb", 14,24, 0x283e, "1L2B", 8, "", DEF_MODEC,DEF_MODEL },
+ { "trunclw", 14,24, 0x293e, "1L2W", 8, "", DEF_MODEC,DEF_MODEL },
+ { "truncld", 14,24, 0x2b3e, "1L2D", 8, "", DEF_MODEC,DEF_MODEL },
+ { "wait", 8,8, 0xb2, "", 0, "", DEF_MODEC,DEF_MODEL },
+ { "wrval", 19,24, 0x0071e,"1A", 0, "", DEF_MODEC,DEF_MODEL },
+ { "xorb", 6,16, 0x38, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "xorw", 6,16, 0x39, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "xord", 6,16, 0x3b, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+#if defined(NS32381) /* I'm not too sure of these */
+ { "dotf", 14,24, 0x0dfe, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "dotl", 14,24, 0x0cfe, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "logbf", 14,24, 0x15fe, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "logbl", 14,24, 0x14fe, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "polyf", 14,24, 0x09fe, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "polyl", 14,24, 0x08fe, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "scalbf", 14,24, 0x11fe, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "scalbl", 14,24, 0x10fe, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+#endif
+};
+
+int numopcodes=sizeof(ns32k_opcodes)/sizeof(ns32k_opcodes[0]);
+
+struct ns32k_opcode *endop = ns32k_opcodes+sizeof(ns32k_opcodes)/sizeof(ns32k_opcodes[0]);
+
+#define MAX_ARGS 4
+#define ARG_LEN 50
+
diff --git a/gnu/usr.bin/gas/config/ns32k.c b/gnu/usr.bin/gas/config/ns32k.c
new file mode 100644
index 00000000000..8db917b243f
--- /dev/null
+++ b/gnu/usr.bin/gas/config/ns32k.c
@@ -0,0 +1,1768 @@
+/* ns32k.c -- Assemble on the National Semiconductor 32k series
+ Copyright (C) 1987 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#define NS32K
+/*#define SHOW_NUM 1*/ /* uncomment for debugging */
+
+#include <stdio.h>
+#include <ctype.h>
+#ifdef USG
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include "ns32k-opcode.h"
+#include "as.h"
+#include "obstack.h"
+#include "frags.h"
+#include "struc-symbol.h"
+#include "flonum.h"
+#include "expr.h"
+#include "md.h"
+#include "hash.h"
+#include "write.h"
+#include "symbols.h"
+
+/* Macros */
+#define IIF_ENTRIES 13 /* number of entries in iif */
+#define PRIVATE_SIZE 256 /* size of my garbage memory */
+#define MAX_ARGS 4
+#define DEFAULT -1 /* addr_mode returns this value when plain constant or label is encountered */
+
+#define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1) \
+ iif.iifP[ptr].type= a1; \
+ iif.iifP[ptr].size= c1; \
+ iif.iifP[ptr].object= e1; \
+ iif.iifP[ptr].object_adjust= g1; \
+ iif.iifP[ptr].pcrel= i1; \
+ iif.iifP[ptr].pcrel_adjust= k1; \
+ iif.iifP[ptr].im_disp= m1; \
+ iif.iifP[ptr].relax_substate= o1; \
+ iif.iifP[ptr].bit_fixP= q1; \
+ iif.iifP[ptr].addr_mode= s1; \
+ iif.iifP[ptr].bsr= u1;
+
+#ifdef SEQUENT_COMPATABILITY
+#define LINE_COMMENT_CHARS "|"
+#define ABSOLUTE_PREFIX '@'
+#define IMMEDIATE_PREFIX '#'
+#endif
+
+#ifndef LINE_COMMENT_CHARS
+#define LINE_COMMENT_CHARS "#"
+#endif
+
+char comment_chars[] = "#";
+char line_comment_chars[] = LINE_COMMENT_CHARS;
+#if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX)
+#define ABSOLUTE_PREFIX '@' /* One or the other MUST be defined */
+#endif
+
+struct addr_mode {
+ char mode; /* addressing mode of operand (0-31) */
+ char scaled_mode; /* mode combined with scaled mode */
+ char scaled_reg; /* register used in scaled+1 (1-8) */
+ char float_flag; /* set if R0..R7 was F0..F7 ie a floating-point-register */
+ char am_size; /* estimated max size of general addr-mode parts*/
+ char im_disp; /* if im_disp==1 we have a displacement */
+ char pcrel; /* 1 if pcrel, this is really redundant info */
+ char disp_suffix[2]; /* length of displacement(s), 0=undefined */
+ char *disp[2]; /* pointer(s) at displacement(s)
+ or immediates(s) (ascii) */
+ char index_byte; /* index byte */
+};
+typedef struct addr_mode addr_modeS;
+
+
+char *freeptr,*freeptr_static; /* points at some number of free bytes */
+struct hash_control *inst_hash_handle;
+
+struct ns32k_opcode *desc; /* pointer at description of instruction */
+addr_modeS addr_modeP;
+char EXP_CHARS[] = "eE";
+char FLT_CHARS[] = "fd"; /* we don't want to support lowercase, do we */
+long omagic = OMAGIC;
+void md_number_to_disp();
+void md_number_to_imm();
+segT evaluate_expr();
+void fix_new_ns32k();
+
+/* UPPERCASE denotes live names
+ * when an instruction is built, IIF is used as an intermidiate form to store
+ * the actual parts of the instruction. A ns32k machine instruction can
+ * be divided into a couple of sub PARTs. When an instruction is assembled
+ * the appropriate PART get an assignment. When an IIF has been completed it's
+ * converted to a FRAGment as specified in AS.H */
+
+/* internal structs */
+struct option {
+ char *pattern;
+ unsigned long or;
+ unsigned long and;
+};
+
+typedef struct {
+ int type; /* how to interpret object */
+ int size; /* Estimated max size of object */
+ unsigned long object; /* binary data */
+ int object_adjust; /* number added to object */
+ int pcrel; /* True if object is pcrel */
+ int pcrel_adjust; /* It's value reflects the length in bytes from the instruction start to the displacement */
+ int im_disp; /* True if the object is a displacement */
+ relax_substateT relax_substate; /* Initial relaxsubstate */
+ bit_fixS *bit_fixP; /* Pointer at bit_fix struct */
+ int addr_mode; /* What addrmode do we associate with this iif-entry */
+ char bsr; /* Sequent hack */
+}iif_entryT; /* Internal Instruction Format */
+struct int_ins_form {
+ int instr_size; /* Max size of instruction in bytes. */
+ iif_entryT iifP[IIF_ENTRIES+1];
+};
+struct int_ins_form iif;
+expressionS exprP;
+char *input_line_pointer;
+/* description of the PARTs in IIF
+ *object[n]:
+ * 0 total length in bytes of entries in iif
+ * 1 opcode
+ * 2 index_byte_a
+ * 3 index_byte_b
+ * 4 disp_a_1
+ * 5 disp_a_2
+ * 6 disp_b_1
+ * 7 disp_b_2
+ * 8 imm_a
+ * 9 imm_b
+ * 10 implied1
+ * 11 implied2
+ *
+ * For every entry there is a datalength in bytes. This is stored in size[n].
+ * 0, the objectlength is not explicitly given by the instruction
+ * and the operand is undefined. This is a case for relaxation.
+ * Reserve 4 bytes for the final object.
+ *
+ * 1, the entry contains one byte
+ * 2, the entry contains two bytes
+ * 3, the entry contains three bytes
+ * 4, the entry contains four bytes
+ * etc
+ *
+ * Furthermore, every entry has a data type identifier in type[n].
+ *
+ * 0, the entry is void, ignore it.
+ * 1, the entry is a binary number.
+ * 2, the entry is a pointer at an expression.
+ * Where expression may be as simple as a single '1',
+ * and as complicated as foo-bar+12,
+ * foo and bar may be undefined but suffixed by :{b|w|d} to
+ * control the length of the object.
+ *
+ * 3, the entry is a pointer at a bignum struct
+ *
+ *
+ * The low-order-byte coresponds to low physical memory.
+ * Obviously a FRAGment must be created for each valid disp in PART whose
+ * datalength is undefined (to bad) .
+ * The case where just the expression is undefined is less severe and is
+ * handled by fix. Here the number of bytes in the objectfile is known.
+ * With this representation we simplify the assembly and separates the
+ * machine dependent/independent parts in a more clean way (said OE)
+ */
+
+struct option opt1[]= /* restore, exit */
+{
+ { "r0", 0x80, 0xff },
+ { "r1", 0x40, 0xff },
+ { "r2", 0x20, 0xff },
+ { "r3", 0x10, 0xff },
+ { "r4", 0x08, 0xff },
+ { "r5", 0x04, 0xff },
+ { "r6", 0x02, 0xff },
+ { "r7", 0x01, 0xff },
+ { 0 , 0x00, 0xff }
+};
+struct option opt2[]= /* save, enter */
+{
+ { "r0", 0x01, 0xff },
+ { "r1", 0x02, 0xff },
+ { "r2", 0x04, 0xff },
+ { "r3", 0x08, 0xff },
+ { "r4", 0x10, 0xff },
+ { "r5", 0x20, 0xff },
+ { "r6", 0x40, 0xff },
+ { "r7", 0x80, 0xff },
+ { 0 , 0x00, 0xff }
+};
+struct option opt3[]= /* setcfg */
+{
+ { "c", 0x8, 0xff },
+ { "m", 0x4, 0xff },
+ { "f", 0x2, 0xff },
+ { "i", 0x1, 0xff },
+ { 0 , 0x0, 0xff }
+};
+struct option opt4[]= /* cinv */
+{
+ { "a", 0x4, 0xff },
+ { "i", 0x2, 0xff },
+ { "d", 0x1, 0xff },
+ { 0 , 0x0, 0xff }
+};
+struct option opt5[]= /* string inst */
+{
+ { "b", 0x2, 0xff },
+ { "u", 0xc, 0xff },
+ { "w", 0x4, 0xff },
+ { 0 , 0x0, 0xff }
+};
+struct option opt6[]= /* plain reg ext,cvtp etc */
+{
+ { "r0", 0x00, 0xff },
+ { "r1", 0x01, 0xff },
+ { "r2", 0x02, 0xff },
+ { "r3", 0x03, 0xff },
+ { "r4", 0x04, 0xff },
+ { "r5", 0x05, 0xff },
+ { "r6", 0x06, 0xff },
+ { "r7", 0x07, 0xff },
+ { 0 , 0x00, 0xff }
+};
+
+#if !defined(NS32032) && !defined(NS32532)
+#define NS32032
+#endif
+
+struct option cpureg_532[]= /* lpr spr */
+{
+ { "us", 0x0, 0xff },
+ { "dcr", 0x1, 0xff },
+ { "bpc", 0x2, 0xff },
+ { "dsr", 0x3, 0xff },
+ { "car", 0x4, 0xff },
+ { "fp", 0x8, 0xff },
+ { "sp", 0x9, 0xff },
+ { "sb", 0xa, 0xff },
+ { "usp", 0xb, 0xff },
+ { "cfg", 0xc, 0xff },
+ { "psr", 0xd, 0xff },
+ { "intbase", 0xe, 0xff },
+ { "mod", 0xf, 0xff },
+ { 0 , 0x00, 0xff }
+};
+struct option mmureg_532[]= /* lmr smr */
+{
+ { "mcr", 0x9, 0xff },
+ { "msr", 0xa, 0xff },
+ { "tear", 0xb, 0xff },
+ { "ptb0", 0xc, 0xff },
+ { "ptb1", 0xd, 0xff },
+ { "ivar0", 0xe, 0xff },
+ { "ivar1", 0xf, 0xff },
+ { 0 , 0x0, 0xff }
+};
+
+struct option cpureg_032[]= /* lpr spr */
+{
+ { "upsr", 0x0, 0xff },
+ { "fp", 0x8, 0xff },
+ { "sp", 0x9, 0xff },
+ { "sb", 0xa, 0xff },
+ { "psr", 0xd, 0xff },
+ { "intbase", 0xe, 0xff },
+ { "mod", 0xf, 0xff },
+ { 0 , 0x0, 0xff }
+};
+struct option mmureg_032[]= /* lmr smr */
+{
+ { "bpr0", 0x0, 0xff },
+ { "bpr1", 0x1, 0xff },
+ { "pf0", 0x4, 0xff },
+ { "pf1", 0x5, 0xff },
+ { "sc", 0x8, 0xff },
+ { "msr", 0xa, 0xff },
+ { "bcnt", 0xb, 0xff },
+ { "ptb0", 0xc, 0xff },
+ { "ptb1", 0xd, 0xff },
+ { "eia", 0xf, 0xff },
+ { 0 , 0x0, 0xff }
+};
+
+#if defined(NS32532)
+struct option *cpureg = cpureg_532;
+struct option *mmureg = mmureg_532;
+#else
+struct option *cpureg = cpureg_032;
+struct option *mmureg = mmureg_032;
+#endif
+
+
+const pseudo_typeS md_pseudo_table[]={ /* so far empty */
+ { 0, 0, 0 }
+};
+
+#define IND(x,y) (((x)<<2)+(y))
+
+/* those are index's to relax groups in md_relax_table
+ ie it must be multiplied by 4 to point at a group start. Viz IND(x,y)
+ Se function relax_segment in write.c for more info */
+
+#define BRANCH 1
+#define PCREL 2
+
+/* those are index's to entries in a relax group */
+
+#define BYTE 0
+#define WORD 1
+#define DOUBLE 2
+#define UNDEF 3
+/* Those limits are calculated from the displacement start in memory.
+ The ns32k uses the begining of the instruction as displacement base.
+ This type of displacements could be handled here by moving the limit window
+ up or down. I choose to use an internal displacement base-adjust as there
+ are other routines that must consider this. Also, as we have two various
+ offset-adjusts in the ns32k (acb versus br/brs/jsr/bcond), two set of limits
+ would have had to be used.
+ Now we dont have to think about that. */
+
+
+const relax_typeS md_relax_table[]={
+ { 1, 1, 0, 0 },
+ { 1, 1, 0, 0 },
+ { 1, 1, 0, 0 },
+ { 1, 1, 0, 0 },
+
+ { (63), (-64), 1, IND(BRANCH,WORD) },
+ { (8192), (-8192), 2, IND(BRANCH,DOUBLE) },
+ { 0, 0, 4, 0 },
+ { 1, 1, 0, 0 }
+};
+
+/* Array used to test if mode contains displacements.
+ Value is true if mode contains displacement. */
+
+char disp_test[]={ 0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,
+ 1,1,1,0,0,1,1,0,
+ 1,1,1,1,1,1,1,1 };
+
+/* Array used to calculate max size of displacements */
+
+char disp_size[]={ 4,1,2,0,4 };
+
+/* Parses a general operand into an addressingmode struct
+
+ in: pointer at operand in ascii form
+ pointer at addr_mode struct for result
+ the level of recursion. (always 0 or 1)
+
+ out: data in addr_mode struct
+ */
+int addr_mode(operand,addr_modeP,recursive_level)
+ char *operand;
+ register addr_modeS *addr_modeP;
+int recursive_level;
+{
+ register char *str;
+ register int i;
+ register int strl;
+ register int mode;
+ int j;
+ mode = DEFAULT; /* default */
+ addr_modeP->scaled_mode=0; /* why not */
+ addr_modeP->scaled_reg=0; /* if 0, not scaled index */
+ addr_modeP->float_flag=0;
+ addr_modeP->am_size=0;
+ addr_modeP->im_disp=0;
+ addr_modeP->pcrel=0; /* not set in this function */
+ addr_modeP->disp_suffix[0]=0;
+ addr_modeP->disp_suffix[1]=0;
+ addr_modeP->disp[0]=NULL;
+ addr_modeP->disp[1]=NULL;
+ str=operand;
+ if (str[0]==0) {return (0);} /* we don't want this */
+ strl=strlen(str);
+ switch (str[0]) {
+ /* the following three case statements controls the mode-chars
+ this is the place to ed if you want to change them */
+#ifdef ABSOLUTE_PREFIX
+ case ABSOLUTE_PREFIX:
+ if (str[strl-1]==']') break;
+ addr_modeP->mode=21; /* absolute */
+ addr_modeP->disp[0]=str+1;
+ return (-1);
+#endif
+#ifdef IMMEDIATE_PREFIX
+ case IMMEDIATE_PREFIX:
+ if (str[strl-1]==']') break;
+ addr_modeP->mode=20; /* immediate */
+ addr_modeP->disp[0]=str+1;
+ return (-1);
+#endif
+ case '.':
+ if (str[strl-1]!=']') {
+ switch (str[1]) {
+ case'-':case'+':
+ if (str[2]!='\000') {
+ addr_modeP->mode=27; /* pc-relativ */
+ addr_modeP->disp[0]=str+2;
+ return (-1);
+ }
+ default:
+ as_warn("Invalid syntax in PC-relative addressing mode");
+ return(0);
+ }
+ }
+ break;
+ case'e':
+ if (str[strl-1]!=']') {
+ if((!strncmp(str,"ext(",4)) && strl>7) { /* external */
+ addr_modeP->disp[0]=str+4;
+ i=0;
+ j=2;
+ do { /* disp[0]'s termination point */
+ j+=1;
+ if (str[j]=='(') i++;
+ if (str[j]==')') i--;
+ } while (j<strl && i!=0);
+ if (i!=0 || !(str[j+1]=='-' || str[j+1]=='+') ) {
+ as_warn("Invalid syntax in External addressing mode");
+ return(0);
+ }
+ str[j]='\000'; /* null terminate disp[0] */
+ addr_modeP->disp[1]=str+j+2;
+ addr_modeP->mode=22;
+ return (-1);
+ }
+ }
+ break;
+ default:;
+ }
+ strl=strlen(str);
+ switch(strl) {
+ case 2:
+ switch (str[0]) {
+ case'f':addr_modeP->float_flag=1;
+ case'r':
+ if (str[1]>='0' && str[1]<'8') {
+ addr_modeP->mode=str[1]-'0';
+ return (-1);
+ }
+ }
+ case 3:
+ if (!strncmp(str,"tos",3)) {
+ addr_modeP->mode=23; /* TopOfStack */
+ return (-1);
+ }
+ default:;
+ }
+ if (strl>4) {
+ if (str[strl-1]==')') {
+ if (str[strl-2]==')') {
+ if (!strncmp(&str[strl-5],"(fp",3)) {
+ mode=16; /* Memory Relative */
+ }
+ if (!strncmp(&str[strl-5],"(sp",3)) {
+ mode=17;
+ }
+ if (!strncmp(&str[strl-5],"(sb",3)) {
+ mode=18;
+ }
+ if (mode!=DEFAULT) { /* memory relative */
+ addr_modeP->mode=mode;
+ j=strl-5; /* temp for end of disp[0] */
+ i=0;
+ do {
+ strl-=1;
+ if (str[strl]==')') i++;
+ if (str[strl]=='(') i--;
+ } while (strl>-1 && i!=0);
+ if (i!=0) {
+ as_warn("Invalid syntax in Memory Relative addressing mode");
+ return(0);
+ }
+ addr_modeP->disp[1]=str;
+ addr_modeP->disp[0]=str+strl+1;
+ str[j]='\000'; /* null terminate disp[0] */
+ str[strl]='\000'; /* null terminate disp[1] */
+ return (-1);
+ }
+ }
+ switch (str[strl-3]) {
+ case'r':case'R':
+ if (str[strl-2]>='0' && str[strl-2]<'8' && str[strl-4]=='(') {
+ addr_modeP->mode=str[strl-2]-'0'+8;
+ addr_modeP->disp[0]=str;
+ str[strl-4]=0;
+ return (-1); /* reg rel */
+ }
+ default:
+ if (!strncmp(&str[strl-4],"(fp",3)) {
+ mode=24;
+ }
+ if (!strncmp(&str[strl-4],"(sp",3)) {
+ mode=25;
+ }
+ if (!strncmp(&str[strl-4],"(sb",3)) {
+ mode=26;
+ }
+ if (!strncmp(&str[strl-4],"(pc",3)) {
+ mode=27;
+ }
+ if (mode!=DEFAULT) {
+ addr_modeP->mode=mode;
+ addr_modeP->disp[0]=str;
+ str[strl-4]='\0';
+ return (-1); /* memory space */
+ }
+ }
+ }
+ /* no trailing ')' do we have a ']' ? */
+ if (str[strl-1]==']') {
+ switch (str[strl-2]) {
+ case'b':mode=28;break;
+ case'w':mode=29;break;
+ case'd':mode=30;break;
+ case'q':mode=31;break;
+ default:;
+ as_warn("Invalid scaled-indexed mode, use (b,w,d,q)");
+ if (str[strl-3]!=':' || str[strl-6]!='[' ||
+ str[strl-5]=='r' || str[strl-4]<'0' || str[strl-4]>'7') {
+ as_warn("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}");
+ }
+ } /* scaled index */
+ {
+ if (recursive_level>0) {
+ as_warn("Scaled-indexed addressing mode combined with scaled-index");
+ return(0);
+ }
+ addr_modeP->am_size+=1; /* scaled index byte */
+ j=str[strl-4]-'0'; /* store temporary */
+ str[strl-6]='\000'; /* nullterminate for recursive call */
+ i=addr_mode(str,addr_modeP,1);
+ if (!i || addr_modeP->mode==20) {
+ as_warn("Invalid or illegal addressing mode combined with scaled-index");
+ return(0);
+ }
+ addr_modeP->scaled_mode=addr_modeP->mode; /* store the inferior mode */
+ addr_modeP->mode=mode;
+ addr_modeP->scaled_reg=j+1;
+ return (-1);
+ }
+ }
+ }
+ addr_modeP->mode = DEFAULT; /* default to whatever */
+ addr_modeP->disp[0]=str;
+ return (-1);
+}
+
+/* ptr points at string
+ addr_modeP points at struct with result
+ This routine calls addr_mode to determine the general addr.mode of
+ the operand. When this is ready it parses the displacements for size
+ specifying suffixes and determines size of immediate mode via ns32k-opcode.
+ Also builds index bytes if needed.
+ */
+int get_addr_mode(ptr,addr_modeP)
+ char *ptr;
+ addr_modeS *addr_modeP;
+{
+ int tmp;
+ addr_mode(ptr,addr_modeP,0);
+ if (addr_modeP->mode == DEFAULT || addr_modeP->scaled_mode == -1) {
+ /* resolve ambigious operands, this shouldn't
+ be necessary if one uses standard NSC operand
+ syntax. But the sequent compiler doesn't!!!
+ This finds a proper addressinging mode if it
+ is implicitly stated. See ns32k-opcode.h */
+ (void)evaluate_expr(&exprP,ptr); /* this call takes time Sigh! */
+ if (addr_modeP->mode == DEFAULT) {
+ if (exprP.X_add_symbol || exprP.X_subtract_symbol) {
+ addr_modeP->mode=desc->default_model; /* we have a label */
+ } else {
+ addr_modeP->mode=desc->default_modec; /* we have a constant */
+ }
+ } else {
+ if (exprP.X_add_symbol || exprP.X_subtract_symbol) {
+ addr_modeP->scaled_mode=desc->default_model;
+ } else {
+ addr_modeP->scaled_mode=desc->default_modec;
+ }
+ }
+ /* must put this mess down in addr_mode to handle the scaled case better */
+ }
+ /* It appears as the sequent compiler wants an absolute when we have a
+ label without @. Constants becomes immediates besides the addr case.
+ Think it does so with local labels too, not optimum, pcrel is better.
+ When I have time I will make gas check this and select pcrel when possible
+ Actually that is trivial.
+ */
+ if (tmp=addr_modeP->scaled_reg) { /* build indexbyte */
+ tmp--; /* remember regnumber comes incremented for flagpurpose */
+ tmp|=addr_modeP->scaled_mode<<3;
+ addr_modeP->index_byte=(char)tmp;
+ addr_modeP->am_size+=1;
+ }
+ if (disp_test[addr_modeP->mode]) { /* there was a displacement, probe for length specifying suffix*/
+ {
+ register char c;
+ register char suffix;
+ register char suffix_sub;
+ register int i;
+ register char *toP;
+ register char *fromP;
+
+ addr_modeP->pcrel=0;
+ if (disp_test[addr_modeP->mode]) { /* there is a displacement */
+ if (addr_modeP->mode==27 || addr_modeP->scaled_mode==27) { /* do we have pcrel. mode */
+ addr_modeP->pcrel=1;
+ }
+ addr_modeP->im_disp=1;
+ for(i=0;i<2;i++) {
+ suffix_sub=suffix=0;
+ if (toP=addr_modeP->disp[i]) { /* suffix of expression, the largest size rules */
+ fromP=toP;
+ while (c = *fromP++) {
+ *toP++=c;
+ if (c==':') {
+ switch (*fromP) {
+ case '\0':
+ as_warn("Premature end of suffix--Defaulting to d");
+ suffix=4;
+ continue;
+ case 'b':suffix_sub=1;break;
+ case 'w':suffix_sub=2;break;
+ case 'd':suffix_sub=4;break;
+ default:
+ as_warn("Bad suffix after ':' use {b|w|d} Defaulting to d");
+ suffix=4;
+ }
+ fromP++;
+ toP--; /* So we write over the ':' */
+ if (suffix<suffix_sub) suffix=suffix_sub;
+ }
+ }
+ *toP='\0'; /* terminate properly */
+ addr_modeP->disp_suffix[i]=suffix;
+ addr_modeP->am_size+=suffix ? suffix : 4;
+ }
+ }
+ }
+ }
+ } else {
+ if (addr_modeP->mode==20) { /* look in ns32k_opcode for size */
+ addr_modeP->disp_suffix[0]=addr_modeP->am_size=desc->im_size;
+ addr_modeP->im_disp=0;
+ }
+ }
+ return addr_modeP->mode;
+}
+
+
+/* read an optionlist */
+void optlist(str,optionP,default_map)
+ char *str; /* the string to extract options from */
+ struct option *optionP; /* how to search the string */
+ unsigned long *default_map; /* default pattern and output */
+{
+ register int i,j,k,strlen1,strlen2;
+ register char *patternP,*strP;
+ strlen1=strlen(str);
+ if (strlen1<1) {
+ as_fatal("Very short instr to option, ie you can't do it on a NULLstr");
+ }
+ for (i=0;optionP[i].pattern!=0;i++) {
+ strlen2=strlen(optionP[i].pattern);
+ for (j=0;j<strlen1;j++) {
+ patternP=optionP[i].pattern;
+ strP = &str[j];
+ for (k=0;k<strlen2;k++) {
+ if (*(strP++)!=*(patternP++)) break;
+ }
+ if (k==strlen2) { /* match */
+ *default_map|=optionP[i].or;
+ *default_map&=optionP[i].and;
+ }
+ }
+ }
+}
+/* search struct for symbols
+ This function is used to get the short integer form of reg names
+ in the instructions lmr, smr, lpr, spr
+ return true if str is found in list */
+
+int list_search(str,optionP,default_map)
+ char *str; /* the string to match */
+ struct option *optionP; /* list to search */
+ unsigned long *default_map; /* default pattern and output */
+{
+ register int i;
+ for (i=0;optionP[i].pattern!=0;i++) {
+ if (!strncmp(optionP[i].pattern,str,20)) { /* use strncmp to be safe */
+ *default_map|=optionP[i].or;
+ *default_map&=optionP[i].and;
+ return -1;
+ }
+ }
+ as_warn("No such entry in list. (cpu/mmu register)");
+ return 0;
+}
+segT evaluate_expr(resultP,ptr)
+expressionS *resultP;
+char *ptr;
+{
+ register char *tmp_line;
+ register segT segment;
+ tmp_line=input_line_pointer;
+ input_line_pointer=ptr;
+ segment=expression(&exprP);
+ input_line_pointer=tmp_line;
+ return (segment);
+}
+
+/* Convert operands to iif-format and adds bitfields to the opcode.
+ Operands are parsed in such an order that the opcode is updated from
+ its most significant bit, that is when the operand need to alter the
+ opcode.
+ Be carefull not to put to objects in the same iif-slot.
+ */
+
+encode_operand(argc,argv,operandsP,suffixP,im_size,opcode_bit_ptr)
+ int argc;
+ char **argv;
+ char *operandsP;
+ char *suffixP;
+ char im_size;
+ char opcode_bit_ptr;
+{
+ register int i,j;
+ int pcrel,tmp,b,loop,pcrel_adjust;
+ for(loop=0;loop<argc;loop++) {
+ i=operandsP[loop<<1]-'1'; /* what operand are we supposed to work on */
+ if (i>3) as_fatal("Internal error check ns32k-opcode.h");
+ pcrel=0;
+ pcrel_adjust=0;
+ tmp=0;
+ switch (operandsP[(loop<<1)+1]) {
+ case 'f': /* operand of sfsr turns out to be a nasty specialcase */
+ opcode_bit_ptr-=5;
+ case 'F': /* 32 bit float general form */
+ case 'L': /* 64 bit float */
+ case 'Q': /* quad-word */
+ case 'B': /* byte */
+ case 'W': /* word */
+ case 'D': /* double-word */
+ case 'A': /* double-word gen-address-form ie no regs allowed */
+ get_addr_mode(argv[i],&addr_modeP);
+ iif.instr_size+=addr_modeP.am_size;
+ if (opcode_bit_ptr==desc->opcode_size) b=4; else b=6;
+ for (j=b;j<(b+2);j++) {
+ if (addr_modeP.disp[j-b]) {
+ IIF(j,
+ 2,
+ addr_modeP.disp_suffix[j-b],
+ (unsigned long)addr_modeP.disp[j-b],
+ 0,
+ addr_modeP.pcrel,
+ iif.instr_size-addr_modeP.am_size, /* this aint used (now) */
+ addr_modeP.im_disp,
+ IND(BRANCH,BYTE),
+ NULL,
+ addr_modeP.scaled_reg ? addr_modeP.scaled_mode:addr_modeP.mode,
+ 0);
+ }
+ }
+ opcode_bit_ptr-=5;
+ iif.iifP[1].object|=((long)addr_modeP.mode)<<opcode_bit_ptr;
+ if (addr_modeP.scaled_reg) {
+ j=b/2;
+ IIF(j,1,1, (unsigned long)addr_modeP.index_byte,0,0,0,0,0, NULL,-1,0);
+ }
+ break;
+ case 'b': /* multiple instruction disp */
+ freeptr++; /* OVE:this is an useful hack */
+ tmp=(int)sprintf(freeptr,"((%s-1)*%d)\000",argv[i],desc->im_size);
+ argv[i]=freeptr;
+ freeptr=(char*)tmp;
+ pcrel-=1; /* make pcrel 0 inspite of what case 'p': wants */
+ /* fall thru */
+ case 'p': /* displacement - pc relative addressing */
+ pcrel+=1;
+ /* fall thru */
+ case 'd': /* displacement */
+ iif.instr_size+=suffixP[i] ? suffixP[i] : 4;
+ IIF(12, 2, suffixP[i], (unsigned long)argv[i], 0,
+ pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1,0);
+ break;
+ case 'H': /* sequent-hack: the linker wants a bit set when bsr */
+ pcrel=1;
+ iif.instr_size+=suffixP[i] ? suffixP[i] : 4;
+ IIF(12, 2, suffixP[i], (unsigned long)argv[i], 0,
+ pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1,1);break;
+ case 'q': /* quick */
+ opcode_bit_ptr-=4;
+ IIF(11,2,42,(unsigned long)argv[i],0,0,0,0,0,
+ bit_fix_new(4,opcode_bit_ptr,-8,7,0,1,0),-1,0);
+ break;
+ case 'r': /* register number (3 bits) */
+ list_search(argv[i],opt6,&tmp);
+ opcode_bit_ptr-=3;
+ iif.iifP[1].object|=tmp<<opcode_bit_ptr;
+ break;
+ case 'O': /* setcfg instruction optionslist */
+ optlist(argv[i],opt3,&tmp);
+ opcode_bit_ptr-=4;
+ iif.iifP[1].object|=tmp<<15;
+ break;
+ case 'C': /* cinv instruction optionslist */
+ optlist(argv[i],opt4,&tmp);
+ opcode_bit_ptr-=4;
+ iif.iifP[1].object|=tmp<<15;/*insert the regtype in opcode */
+ break;
+ case 'S': /* stringinstruction optionslist */
+ optlist(argv[i],opt5,&tmp);
+ opcode_bit_ptr-=4;
+ iif.iifP[1].object|=tmp<<15;
+ break;
+ case 'u':case 'U': /* registerlist */
+ IIF(10,1,1,0,0,0,0,0,0,NULL,-1,0);
+ switch (operandsP[(i<<1)+1]) {
+ case 'u': /* restore, exit */
+ optlist(argv[i],opt1,&iif.iifP[10].object);
+ break;
+ case 'U': /* save,enter */
+ optlist(argv[i],opt2,&iif.iifP[10].object);
+ break;
+ }
+ iif.instr_size+=1;
+ break;
+ case 'M': /* mmu register */
+ list_search(argv[i],mmureg,&tmp);
+ opcode_bit_ptr-=4;
+ iif.iifP[1].object|=tmp<<opcode_bit_ptr;
+ break;
+ case 'P': /* cpu register */
+ list_search(argv[i],cpureg,&tmp);
+ opcode_bit_ptr-=4;
+ iif.iifP[1].object|=tmp<<opcode_bit_ptr;
+ break;
+ case 'g': /* inss exts */
+ iif.instr_size+=1; /* 1 byte is allocated after the opcode */
+ IIF(10,2,1,
+ (unsigned long)argv[i], /* i always 2 here */
+ 0,0,0,0,0,
+ bit_fix_new(3,5,0,7,0,0,0), /* a bit_fix is targeted to the byte */
+ -1,0);
+ case 'G':
+ IIF(11,2,42,
+ (unsigned long)argv[i], /* i always 3 here */
+ 0,0,0,0,0,
+ bit_fix_new(5,0,1,32,-1,0,-1),-1,0);
+ break;
+ case 'i':
+ iif.instr_size+=1;
+ b=2+i; /* put the extension byte after opcode */
+ IIF(b,2,1,0,0,0,0,0,0,0,-1,0);
+ default:
+ as_fatal("Bad opcode-table-option, check in file ns32k-opcode.h");
+ }
+ }
+}
+
+/* in: instruction line
+ out: internal structure of instruction
+ that has been prepared for direct conversion to fragment(s) and
+ fixes in a systematical fashion
+ Return-value = recursive_level
+*/
+/* build iif of one assembly text line */
+int parse(line,recursive_level)
+ char *line;
+ int recursive_level;
+{
+ register char *lineptr,c,suffix_separator;
+ register int i;
+ int argc,arg_type;
+ char sqr,sep;
+ char suffix[MAX_ARGS],*argv[MAX_ARGS];/* no more than 4 operands */
+ if (recursive_level<=0) { /* called from md_assemble */
+ for (lineptr=line;(*lineptr)!='\0' && (*lineptr)!=' ';lineptr++);
+ c = *lineptr;
+ *lineptr='\0';
+ if (!(desc=(struct ns32k_opcode*)hash_find(inst_hash_handle,line))) {
+ as_fatal("No such opcode");
+ }
+ *lineptr=c;
+ } else {
+ lineptr=line;
+ }
+ argc=0;
+ if (*desc->operands) {
+ if (*lineptr++!='\0') {
+ sqr='[';
+ sep=',';
+ while (*lineptr!='\0') {
+ if (desc->operands[argc<<1]) {
+ suffix[argc]=0;
+ arg_type=desc->operands[(argc<<1)+1];
+ switch (arg_type) {
+ case 'd': case 'b': case 'p': case 'H': /* the operand is supposed to be a displacement */
+ /* Hackwarning: do not forget to update the 4 cases above when editing ns32k-opcode.h */
+ suffix_separator=':';
+ break;
+ default:
+ suffix_separator='\255'; /* if this char occurs we loose */
+ }
+ suffix[argc]=0; /* 0 when no ':' is encountered */
+ argv[argc]=freeptr;
+ *freeptr='\0';
+ while ((c = *lineptr)!='\0' && c!=sep) {
+ if (c==sqr) {
+ if (sqr=='[') {
+ sqr=']';sep='\0';
+ } else {
+ sqr='[';sep=',';
+ }
+ }
+ if (c==suffix_separator) { /* ':' - label/suffix separator */
+ switch (lineptr[1]) {
+ case 'b':suffix[argc]=1;break;
+ case 'w':suffix[argc]=2;break;
+ case 'd':suffix[argc]=4;break;
+ default: as_warn("Bad suffix, defaulting to d");
+ suffix[argc]=4;
+ if (lineptr[1]=='\0' || lineptr[1]==sep) {
+ lineptr+=1;
+ continue;
+ }
+ }
+ lineptr+=2;
+ continue;
+ }
+ *freeptr++=c;
+ lineptr++;
+ }
+ *freeptr++='\0';
+ argc+=1;
+ if (*lineptr=='\0') continue;
+ lineptr+=1;
+ } else {
+ as_fatal("Too many operands passed to instruction");
+ }
+ }
+ }
+ }
+ if (argc!=strlen(desc->operands)/2) {
+ if (strlen(desc->default_args)) { /* we can apply default, dont goof */
+ if (parse(desc->default_args,1)!=1) { /* check error in default */
+ as_fatal("Wrong numbers of operands in default, check ns32k-opcodes.h");
+ }
+ } else {
+ as_fatal("Wrong number of operands");
+ }
+
+ }
+ for (i=0;i<IIF_ENTRIES;i++) {
+ iif.iifP[i].type=0; /* mark all entries as void*/
+ }
+
+ /* build opcode iif-entry */
+ iif.instr_size=desc->opcode_size/8;
+ IIF(1,1,iif.instr_size,desc->opcode_seed,0,0,0,0,0,0,-1,0);
+
+ /* this call encodes operands to iif format */
+ if (argc) {
+ encode_operand(argc,
+ argv,
+ &desc->operands[0],
+ &suffix[0],
+ desc->im_size,
+ desc->opcode_size);
+ }
+ return recursive_level;
+}
+
+
+ /* Convert iif to fragments.
+ From this point we start to dribble with functions in other files than
+ this one.(Except hash.c) So, if it's possible to make an iif for an other
+ CPU, you don't need to know what frags, relax, obstacks, etc is in order
+ to port this assembler. You only need to know if it's possible to reduce
+ your cpu-instruction to iif-format (takes some work) and adopt the other
+ md_? parts according to given instructions
+ Note that iif was invented for the clean ns32k`s architecure.
+ */
+convert_iif()
+{
+ register int i,j;
+ fragS *inst_frag;
+ char *inst_offset,*inst_opcode;
+ char *memP;
+ segT segment;
+ int l,k;
+ register int rem_size; /* count the remaining bytes of instruction */
+ register char type;
+ register char size = 0;
+ int size_so_far=0; /* used to calculate pcrel_adjust */
+
+ rem_size=iif.instr_size;
+ memP=frag_more(iif.instr_size); /* make sure we have enough bytes for instruction */
+ inst_opcode=memP;
+ inst_offset=(char*)(memP-frag_now->fr_literal);
+ inst_frag=frag_now;
+ for (i=0;i<IIF_ENTRIES;i++) {
+ if (type=iif.iifP[i].type) { /* the object exist, so handle it */
+ switch (size=iif.iifP[i].size) {
+ case 42: size=0; /* it's a bitfix that operates on an existing object*/
+ if (iif.iifP[i].bit_fixP->fx_bit_base) { /* expand fx_bit_base to point at opcode */
+ iif.iifP[i].bit_fixP->fx_bit_base=(long)inst_opcode;
+ }
+ case 8: /* bignum or doublefloat */
+ bzero (memP,8);
+ case 1:case 2:case 3:case 4:/* the final size in objectmemory is known */
+ j=(unsigned long)iif.iifP[i].bit_fixP;
+ switch (type) {
+ case 1: /* the object is pure binary */
+ if (j || iif.iifP[i].pcrel) {
+ fix_new_ns32k(frag_now,
+ (long)(memP-frag_now->fr_literal),
+ size,
+ 0,
+ 0,
+ iif.iifP[i].object,
+ iif.iifP[i].pcrel,
+ (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/
+ iif.iifP[i].im_disp,
+ j,
+ iif.iifP[i].bsr); /* sequent hack */
+ } else { /* good, just put them bytes out */
+ switch (iif.iifP[i].im_disp) {
+ case 0:
+ md_number_to_chars(memP,iif.iifP[i].object,size);break;
+ case 1:
+ md_number_to_disp(memP,iif.iifP[i].object,size);break;
+ default: as_fatal("iif convert internal pcrel/binary");
+ }
+ }
+ memP+=size;
+ rem_size-=size;
+ break;
+ case 2: /* the object is a pointer at an expression, so unpack
+ it, note that bignums may result from the expression
+ */
+ if ((segment=evaluate_expr(&exprP,(char*)iif.iifP[i].object))==SEG_BIG || size==8) {
+ if ((k=exprP.X_add_number)>0) { /* we have a bignum ie a quad */
+ /* this can only happens in a long suffixed instruction */
+ bzero(memP,size); /* size normally is 8 */
+ if (k*2>size) as_warn("Bignum too big for long");
+ if (k==3) memP+=2;
+ for (l=0;k>0;k--,l+=2) {
+ md_number_to_chars(memP+l,generic_bignum[l>>1],sizeof(LITTLENUM_TYPE));
+ }
+ } else { /* flonum */
+ LITTLENUM_TYPE words[4];
+
+ switch(size) {
+ case 4:
+ gen_to_words(words,2,8);
+ md_number_to_imm(memP ,(long)words[0],sizeof(LITTLENUM_TYPE));
+ md_number_to_imm(memP+sizeof(LITTLENUM_TYPE),(long)words[1],sizeof(LITTLENUM_TYPE));
+ break;
+ case 8:
+ gen_to_words(words,4,11);
+ md_number_to_imm(memP ,(long)words[0],sizeof(LITTLENUM_TYPE));
+ md_number_to_imm(memP+sizeof(LITTLENUM_TYPE) ,(long)words[1],sizeof(LITTLENUM_TYPE));
+ md_number_to_imm(memP+2*sizeof(LITTLENUM_TYPE),(long)words[2],sizeof(LITTLENUM_TYPE));
+ md_number_to_imm(memP+3*sizeof(LITTLENUM_TYPE),(long)words[3],sizeof(LITTLENUM_TYPE));
+ break;
+ }
+ }
+ memP+=size;
+ rem_size-=size;
+ break;
+ }
+ if (j ||
+ exprP.X_add_symbol ||
+ exprP.X_subtract_symbol ||
+ iif.iifP[i].pcrel) { /* fixit */
+ /* the expression was undefined due to an undefined label */
+ /* create a fix so we can fix the object later */
+ exprP.X_add_number+=iif.iifP[i].object_adjust;
+ fix_new_ns32k(frag_now,
+ (long)(memP-frag_now->fr_literal),
+ size,
+ exprP.X_add_symbol,
+ exprP.X_subtract_symbol,
+ exprP.X_add_number,
+ iif.iifP[i].pcrel,
+ (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/
+ iif.iifP[i].im_disp,
+ j,
+ iif.iifP[i].bsr); /* sequent hack */
+
+ } else { /* good, just put them bytes out */
+ switch (iif.iifP[i].im_disp) {
+ case 0:
+ md_number_to_imm(memP,exprP.X_add_number,size);break;
+ case 1:
+ md_number_to_disp(memP,exprP.X_add_number,size);break;
+ default: as_fatal("iif convert internal pcrel/pointer");
+ }
+ }
+ memP+=size;
+ rem_size-=size;
+ break;
+ default: as_fatal("Internal logic error in iif.iifP[n].type");
+ }
+ break;
+ case 0: /* To bad, the object may be undefined as far as its final
+ nsize in object memory is concerned. The size of the object
+ in objectmemory is not explicitly given.
+ If the object is defined its length can be determined and
+ a fix can replace the frag.
+ */
+ {
+ int temp;
+ segment=evaluate_expr(&exprP,(char*)iif.iifP[i].object);
+ if ((exprP.X_add_symbol || exprP.X_subtract_symbol) &&
+ !iif.iifP[i].pcrel) { /* OVE: hack, clamp to 4 bytes */
+ size=4; /* we dont wan't to frag this, use 4 so it reaches */
+ fix_new_ns32k(frag_now,
+ (long)(memP-frag_now->fr_literal),
+ size,
+ exprP.X_add_symbol,
+ exprP.X_subtract_symbol,
+ exprP.X_add_number,
+ 0, /* never iif.iifP[i].pcrel, */
+ (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/
+ 1, /* always iif.iifP[i].im_disp, */
+ 0,0);
+ memP+=size;
+ rem_size-=4;
+ break; /* exit this absolute hack */
+ }
+
+ if (exprP.X_add_symbol || exprP.X_subtract_symbol) { /* frag it */
+ if (exprP.X_subtract_symbol) { /* We cant relax this case */
+ as_fatal("Can't relax difference");
+ }
+ else {
+ /* at this stage we must undo some of the effect caused
+ by frag_more, ie we must make sure that frag_var causes
+ frag_new to creat a valid fix-size in the frag it`s closing
+ */
+ temp = -(rem_size-4);
+ obstack_blank_fast(&frags,temp);
+ /* we rewind none, some or all of the requested size we
+ requested by the first frag_more for this iif chunk.
+ Note: that we allocate 4 bytes to an object we NOT YET
+ know the size of, thus rem_size-4.
+ */
+ (void)frag_variant(rs_machine_dependent,
+ 4,
+ 0,
+ IND(BRANCH,UNDEF), /* expecting the worst */
+ exprP.X_add_symbol,
+ exprP.X_add_number,
+ (char*)inst_opcode,
+ (char)size_so_far, /*iif.iifP[i].pcrel_adjust);*/
+ iif.iifP[i].bsr); /* sequent linker hack */
+ rem_size-=4;
+ if (rem_size>0) {
+ memP=frag_more(rem_size);
+ }
+ }
+ }
+ else {/* Double work, this is done in md_number_to_disp */
+ exprP.X_add_number;
+ if (-64<=exprP.X_add_number && exprP.X_add_number<=63) {
+ size=1;
+ } else {
+ if (-8192<=exprP.X_add_number && exprP.X_add_number<=8191) {
+ size=2;
+ } else {
+ if (-0x1f000000<=exprP.X_add_number &&
+ exprP.X_add_number<=0x1fffffff)
+ /* if (-0x40000000<=exprP.X_add_number &&
+ exprP.X_add_number<=0x3fffffff) */
+ {
+ size=4;
+ } else {
+ as_warn("Displacement to large for :d");
+ size=4;
+ }
+ }
+ }
+ /* rewind the bytes not used */
+ temp = -(4-size);
+ md_number_to_disp(memP,exprP.X_add_number,size);
+ obstack_blank_fast(&frags,temp);
+ memP+=size;
+ rem_size-=4; /* we allocated this amount */
+ }
+ }
+ break;
+ default:
+ as_fatal("Internal logic error in iif.iifP[].type");
+ }
+ size_so_far+=size;
+ size=0;
+ }
+ }
+}
+
+void md_assemble(line)
+char *line;
+{
+ freeptr=freeptr_static;
+ parse(line,0); /* explode line to more fix form in iif */
+ convert_iif(); /* convert iif to frags, fix's etc */
+#ifdef SHOW_NUM
+ printf(" \t\t\t%s\n",line);
+#endif
+}
+
+
+void md_begin()
+{
+ /* build a hashtable of the instructions */
+ register struct ns32k_opcode *ptr;
+ register char *stat;
+ inst_hash_handle=hash_new();
+ for (ptr=ns32k_opcodes;ptr<endop;ptr++) {
+ if (*(stat=hash_insert(inst_hash_handle,ptr->name,(char*)ptr))) {
+ as_fatal("Can't hash %s: %s",ptr->name,stat); /*fatal*/
+ exit(0);
+ }
+ }
+ freeptr_static=(char*)malloc(PRIVATE_SIZE); /* some private space please! */
+}
+
+
+void
+md_end()
+{
+ free(freeptr_static);
+}
+
+/* Must be equal to MAX_PRECISON in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+/* Turn the string pointed to by litP into a floating point constant of type
+ type, and emit the appropriate bytes. The number of LITTLENUMS emitted
+ is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+char *
+md_atof(type,litP,sizeP)
+char type;
+char *litP;
+int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+ char *atof_ieee();
+
+ switch(type) {
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+ default:
+ *sizeP=0;
+ return "Bad call to MD_ATOF()";
+ }
+ t=atof_ieee(input_line_pointer,type,words);
+ if(t)
+ input_line_pointer=t;
+
+ *sizeP=prec * sizeof(LITTLENUM_TYPE);
+ for(wordP=words+prec;prec--;) {
+ md_number_to_chars(litP,(long)(*--wordP),sizeof(LITTLENUM_TYPE));
+ litP+=sizeof(LITTLENUM_TYPE);
+ }
+ return ""; /* Someone should teach Dean about null pointers */
+}
+
+/* Convert number to chars in correct order */
+
+void
+md_number_to_chars (buf, value, nbytes)
+ char *buf;
+ long int value;
+ int nbytes;
+{
+ while (nbytes--)
+ {
+#ifdef SHOW_NUM
+ printf("%x ",value & 0xff);
+#endif
+ *buf++ = value; /* Lint wants & MASK_CHAR. */
+ value >>= BITS_PER_CHAR;
+ }
+}
+/* Convert number to chars in correct order */
+
+
+
+/* This is a variant of md_numbers_to_chars. The reason for its' existence
+ is the fact that ns32k uses Huffman coded displacements. This implies
+ that the bit order is reversed in displacements and that they are prefixed
+ with a size-tag.
+
+ binary: msb -> lsb 0xxxxxxx byte
+ 10xxxxxx xxxxxxxx word
+ 11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx double word
+
+ This must be taken care of and we do it here!
+ */
+void md_number_to_disp(buf,val,n)
+ char *buf;
+ long val;
+ char n;
+{
+ switch(n) {
+ case 1:
+ if (val < -64 || val > 63)
+ as_warn("Byte displacement out of range. line number not valid");
+ val&=0x7f;
+#ifdef SHOW_NUM
+ printf("%x ",val & 0xff);
+#endif
+ *buf++=val;
+ break;
+ case 2:
+ if (val < -8192 || val > 8191)
+ as_warn("Word displacement out of range. line number not valid");
+ val&=0x3fff;
+ val|=0x8000;
+#ifdef SHOW_NUM
+ printf("%x ",val>>8 & 0xff);
+#endif
+ *buf++=(val>>8);
+#ifdef SHOW_NUM
+ printf("%x ",val & 0xff);
+#endif
+ *buf++=val;
+ break;
+ case 4:
+ if (val < -0x1f000000 || val >= 0x20000000)
+ /* if (val < -0x20000000 || val >= 0x20000000) */
+ as_warn("Double word displacement out of range");
+ val|=0xc0000000;
+#ifdef SHOW_NUM
+ printf("%x ",val>>24 & 0xff);
+#endif
+ *buf++=(val>>24);
+#ifdef SHOW_NUM
+ printf("%x ",val>>16 & 0xff);
+#endif
+ *buf++=(val>>16);
+#ifdef SHOW_NUM
+ printf("%x ",val>>8 & 0xff);
+#endif
+ *buf++=(val>>8);
+#ifdef SHOW_NUM
+ printf("%x ",val & 0xff);
+#endif
+ *buf++=val;
+ break;
+ default:
+ as_fatal("Internal logic error");
+ }
+}
+void md_number_to_imm(buf,val,n)
+ char *buf;
+ long val;
+ char n;
+{
+ switch(n) {
+ case 1:
+#ifdef SHOW_NUM
+ printf("%x ",val & 0xff);
+#endif
+ *buf++=val;
+ break;
+ case 2:
+#ifdef SHOW_NUM
+ printf("%x ",val>>8 & 0xff);
+#endif
+ *buf++=(val>>8);
+#ifdef SHOW_NUM
+ printf("%x ",val & 0xff);
+#endif
+ *buf++=val;
+ break;
+ case 4:
+#ifdef SHOW_NUM
+ printf("%x ",val>>24 & 0xff);
+#endif
+ *buf++=(val>>24);
+#ifdef SHOW_NUM
+ printf("%x ",val>>16 & 0xff);
+#endif
+ *buf++=(val>>16);
+#ifdef SHOW_NUM
+ printf("%x ",val>>8 & 0xff);
+#endif
+ *buf++=(val>>8);
+#ifdef SHOW_NUM
+ printf("%x ",val & 0xff);
+#endif
+ *buf++=val;
+ break;
+ default:
+ as_fatal("Internal logic error");
+ }
+}
+/* the bit-field entries in the relocation_info struct plays hell
+ with the byte-order problems of cross-assembly. So as a hack,
+ I added this mach. dependent ri twiddler. Ugly, but it gets
+ you there. -KWK */
+/* OVE: on a ns32k the twiddling continues at an even deeper level
+ here we have to distinguish between displacements and immediates.
+
+ The sequent has a bit for this. It also has a bit for relocobjects that
+ points at the target for a bsr (BranchSubRoutine) !?!?!?!
+
+ Using [] is importable but fast!! still, its rather funny :-)
+ This md_ri.... is tailored for sequent.
+ */
+
+void md_ri_to_chars(ri_p, ri)
+ struct relocation_info *ri_p, ri;
+{
+ if (ri.r_bsr) {ri.r_pcrel=0;} /* sequent seems to want this */
+ md_number_to_chars((char*)ri_p, ri.r_address, sizeof(ri.r_address));
+ md_number_to_chars((char*)ri_p+4,
+ (long)(ri.r_symbolnum ) |
+ (long)(ri.r_pcrel << 24 ) |
+ (long)(ri.r_length << 25 ) |
+ (long)(ri.r_extern << 27 ) |
+ (long)(ri.r_bsr << 28 ) |
+ (long)(ri.r_disp << 29 ),
+ 4);
+ /* the first and second md_number_to_chars never overlaps (32bit cpu case) */
+}
+
+/* fast bitfiddling support */
+/* mask used to zero bitfield before oring in the true field */
+
+static unsigned long l_mask[]={ 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
+ 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
+ 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
+ 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
+ 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
+ 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
+ 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
+ 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
+ };
+static unsigned long r_mask[]={ 0x00000000, 0x00000001, 0x00000003, 0x00000007,
+ 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
+ 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
+ 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
+ 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
+ 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
+ 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
+ 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
+ };
+#define MASK_BITS 31
+/* Insert bitfield described by field_ptr and val at buf
+ This routine is written for modification of the first 4 bytes pointed
+ to by buf, to yield speed.
+ The ifdef stuff is for selection between a ns32k-dependent routine
+ and a general version. (My advice: use the general version!)
+ */
+
+void md_number_to_field(buf,val,field_ptr)
+ register char *buf;
+ register long val;
+ register bit_fixS *field_ptr;
+{
+ register unsigned long object;
+ register unsigned long mask;
+/* define ENDIAN on a ns32k machine */
+#ifdef ENDIAN
+ register unsigned long *mem_ptr;
+#else
+ register char *mem_ptr;
+#endif
+ if (field_ptr->fx_bit_min<=val && val<=field_ptr->fx_bit_max) {
+#ifdef ENDIAN
+ if (field_ptr->fx_bit_base) { /* override buf */
+ mem_ptr=(unsigned long*)field_ptr->fx_bit_base;
+ } else {
+ mem_ptr=(unsigned long*)buf;
+ }
+#else
+ if (field_ptr->fx_bit_base) { /* override buf */
+ mem_ptr=(char*)field_ptr->fx_bit_base;
+ } else {
+ mem_ptr=buf;
+ }
+#endif
+ mem_ptr+=field_ptr->fx_bit_base_adj;
+#ifdef ENDIAN /* we have a nice ns32k machine with lowbyte at low-physical mem */
+ object = *mem_ptr; /* get some bytes */
+#else /* OVE Goof! the machine is a m68k or dito */
+ /* That takes more byte fiddling */
+ object=0;
+ object|=mem_ptr[3] & 0xff;
+ object<<=8;
+ object|=mem_ptr[2] & 0xff;
+ object<<=8;
+ object|=mem_ptr[1] & 0xff;
+ object<<=8;
+ object|=mem_ptr[0] & 0xff;
+#endif
+ mask=0;
+ mask|=(r_mask[field_ptr->fx_bit_offset]);
+ mask|=(l_mask[field_ptr->fx_bit_offset+field_ptr->fx_bit_size]);
+ object&=mask;
+ val+=field_ptr->fx_bit_add;
+ object|=((val<<field_ptr->fx_bit_offset) & (mask ^ 0xffffffff));
+#ifdef ENDIAN
+ *mem_ptr=object;
+#else
+ mem_ptr[0]=(char)object;
+ object>>=8;
+ mem_ptr[1]=(char)object;
+ object>>=8;
+ mem_ptr[2]=(char)object;
+ object>>=8;
+ mem_ptr[3]=(char)object;
+#endif
+ } else {
+ as_warn("Bit field out of range");
+ }
+}
+
+/* Convert a relaxed displacement to dito in final output */
+
+void
+ md_convert_frag(fragP)
+register fragS *fragP;
+{
+ long disp;
+ long ext;
+
+ /* Address in gas core of the place to store the displacement. */
+ register char *buffer_address = fragP -> fr_fix + fragP -> fr_literal;
+ /* Address in object code of the displacement. */
+ register int object_address = fragP -> fr_fix + fragP -> fr_address;
+
+ know(fragP->fr_symbol);
+
+ /* The displacement of the address, from current location. */
+ disp = (fragP->fr_symbol->sy_value + fragP->fr_offset) - object_address;
+ disp+= fragP->fr_pcrel_adjust;
+
+ switch(fragP->fr_subtype) {
+ case IND(BRANCH,BYTE):
+ ext=1;
+ break;
+ case IND(BRANCH,WORD):
+ ext=2;
+ break;
+ case IND(BRANCH,DOUBLE):
+ ext=4;
+ break;
+ }
+ if(ext) {
+ md_number_to_disp(buffer_address,(long)disp,(int)ext);
+ fragP->fr_fix+=ext;
+ }
+}
+
+
+
+/* This function returns the estimated size a variable object will occupy,
+ one can say that we tries to guess the size of the objects before we
+ actually know it */
+
+md_estimate_size_before_relax(fragP,segtype)
+ register fragS *fragP;
+{
+ int old_fix;
+ old_fix=fragP->fr_fix;
+ switch(fragP->fr_subtype) {
+ case IND(BRANCH,UNDEF):
+ if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
+ /* the symbol has been assigned a value */
+ fragP->fr_subtype=IND(BRANCH,BYTE);
+ } else {
+ /* we don't relax symbols defined in an other segment
+ the thing to do is to assume the object will occupy 4 bytes */
+ fix_new_ns32k(fragP,
+ (int)(fragP->fr_fix),
+ 4,
+ fragP->fr_symbol,
+ (symbolS *)0,
+ fragP->fr_offset,
+ 1,
+ fragP->fr_pcrel_adjust,
+ 1,
+ 0,
+ fragP->fr_bsr); /*sequent hack */
+ fragP->fr_fix+=4;
+ /* fragP->fr_opcode[1]=0xff; */
+ frag_wane(fragP);
+ break;
+ }
+ case IND(BRANCH,BYTE):
+ fragP->fr_var+=1;
+ break;
+ default:
+ break;
+ }
+ return fragP->fr_var + fragP->fr_fix - old_fix;
+}
+
+int md_short_jump_size = 3;
+int md_long_jump_size = 5;
+
+void
+md_create_short_jump(ptr,from_addr,to_addr,frag,to_symbol)
+char *ptr;
+long from_addr,
+ to_addr;
+fragS *frag;
+symbolS *to_symbol;
+{
+ long offset;
+
+ offset = to_addr - from_addr;
+ md_number_to_chars(ptr, (long)0xEA ,1);
+ md_number_to_disp(ptr+1,(long)offset,2);
+}
+
+void
+md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol)
+char *ptr;
+long from_addr,
+ to_addr;
+fragS *frag;
+symbolS *to_symbol;
+{
+ long offset;
+
+ offset= to_addr - from_addr;
+ md_number_to_chars(ptr, (long)0xEA, 2);
+ md_number_to_disp(ptr+2,(long)offset,4);
+}
+
+/* JF this is a new function to parse machine-dep options */
+int
+md_parse_option(argP,cntP,vecP)
+char **argP;
+int *cntP;
+char ***vecP;
+{
+ switch(**argP) {
+ case 'm':
+ (*argP)++;
+
+ if(!strcmp(*argP,"32032")) {
+ cpureg = cpureg_032;
+ mmureg = mmureg_032;
+ } else if(!strcmp(*argP, "32532")) {
+ cpureg = cpureg_532;
+ mmureg = mmureg_532;
+ } else
+ as_warn("Unknown -m option ignored");
+
+ while(**argP)
+ (*argP)++;
+ break;
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * bit_fix_new()
+ *
+ * Create a bit_fixS in obstack 'notes'.
+ * This struct is used to profile the normal fix. If the bit_fixP is a
+ * valid pointer (not NULL) the bit_fix data will be used to format the fix.
+ */
+bit_fixS *
+bit_fix_new (size,offset,min,max,add,base_type,base_adj)
+ char size; /* Length of bitfield */
+ char offset; /* Bit offset to bitfield */
+ long base_type; /* 0 or 1, if 1 it's exploded to opcode ptr */
+ long base_adj;
+ long min; /* Signextended min for bitfield */
+ long max; /* Signextended max for bitfield */
+ long add; /* Add mask, used for huffman prefix */
+{
+ register bit_fixS * bit_fixP;
+
+ bit_fixP = (bit_fixS *)obstack_alloc(&notes,sizeof(bit_fixS));
+
+ bit_fixP -> fx_bit_size = size;
+ bit_fixP -> fx_bit_offset = offset;
+ bit_fixP -> fx_bit_base = base_type;
+ bit_fixP -> fx_bit_base_adj = base_adj;
+ bit_fixP -> fx_bit_max = max;
+ bit_fixP -> fx_bit_min = min;
+ bit_fixP -> fx_bit_add = add;
+
+ return bit_fixP;
+}
+
+void
+fix_new_ns32k (frag, where, size, add_symbol, sub_symbol, offset, pcrel,
+ pcrel_adjust, im_disp, bit_fixP, bsr)
+ fragS * frag; /* Which frag? */
+ int where; /* Where in that frag? */
+ short int size; /* 1, 2 or 4 usually. */
+ symbolS * add_symbol; /* X_add_symbol. */
+ symbolS * sub_symbol; /* X_subtract_symbol. */
+ long int offset; /* X_add_number. */
+ int pcrel; /* TRUE if PC-relative relocation. */
+ char pcrel_adjust; /* not zero if adjustment of pcrel offset is needed */
+ char im_disp; /* true if the value to write is a displacement */
+ bit_fixS *bit_fixP; /* pointer at struct of bit_fix's, ignored if NULL */
+ char bsr; /* sequent-linker-hack: 1 when relocobject is a bsr */
+
+{
+ register fixS * fixP;
+
+ fixP = (fixS *)obstack_alloc(&notes,sizeof(fixS));
+ fixP -> fx_frag = frag;
+ fixP -> fx_where = where;
+ fixP -> fx_size = size;
+ fixP -> fx_addsy = add_symbol;
+ fixP -> fx_subsy = sub_symbol;
+ fixP -> fx_offset = offset;
+ fixP -> fx_pcrel = pcrel;
+ fixP -> fx_pcrel_adjust = pcrel_adjust;
+ fixP -> fx_im_disp = im_disp;
+ fixP -> fx_bit_fixP = bit_fixP;
+ fixP -> fx_bsr = bsr;
+ fixP -> fx_next = * seg_fix_rootP;
+
+ * seg_fix_rootP = fixP;
+}
diff --git a/gnu/usr.bin/gas/config/sparc-opcode.h b/gnu/usr.bin/gas/config/sparc-opcode.h
new file mode 100644
index 00000000000..fa39354f5ad
--- /dev/null
+++ b/gnu/usr.bin/gas/config/sparc-opcode.h
@@ -0,0 +1,636 @@
+/* Table of opcodes for the sparc.
+ Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler, and GDB, the GNU disassembler.
+
+GAS/GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS/GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS or GDB; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined(__STDC__) && !defined(const)
+#define const
+#endif
+
+/*
+ * Structure of an opcode table entry.
+ */
+struct sparc_opcode
+{
+ const char *name;
+ unsigned long int match; /* Bits that must be set. */
+ unsigned long int lose; /* Bits that must not be set. */
+ const char *args;
+ /* Nonzero if this is a delayed branch instruction. */
+ char delayed;
+};
+
+/*
+ All sparc opcodes are 32 bits, except for the `set' instruction (really
+ a macro), which is 64 bits. It is handled as a special case.
+
+ The match component is a mask saying which bits must match a
+ particular opcode in order for an instruction to be an instance
+ of that opcode.
+
+ The args component is a string containing one character
+ for each operand of the instruction.
+
+Kinds of operands:
+ # Number used by optimizer. It is ignored.
+ 1 rs1 register.
+ 2 rs2 register.
+ d rd register.
+ e frs1 floating point register.
+ f frs2 floating point register.
+ g frsd floating point register.
+ b crs1 coprocessor register
+ c crs2 coprocessor register
+ D crsd coprocessor register
+ h 22 high bits.
+ i 13 bit Immediate.
+ l 22 bit PC relative immediate.
+ L 30 bit PC relative immediate.
+ a Annul. The annul bit is set.
+ A Alternate address space. Stored as 8 bits.
+ C Coprocessor state register.
+ F floating point state register.
+ p Processor state register.
+ q Floating point queue.
+ r Single register that is both rs1 and rsd.
+ Q Coprocessor queue.
+ S Special case.
+ t Trap base register.
+ w Window invalid mask register.
+ y Y register.
+
+*/
+
+/* The order of the opcodes in this table is significant:
+
+ * The assembler requires that all instances of the same mnemonic must be
+ consecutive. If they aren't, the assembler will bomb at runtime.
+
+ * The disassembler should not care about the order of the opcodes. */
+
+static struct sparc_opcode sparc_opcodes[] =
+{
+
+{ "ldd", 0xc1980000, 0x0060201f, "[1],D", 0 }, /* ldd [rs1+%g0],d */
+{ "ldd", 0xc1982000, 0x00601fff, "[1],D", 0 }, /* ldd [rs1+0],d */
+{ "ldd", 0xc1982000, 0x00600000, "[1+i],D", 0 },
+{ "ldd", 0xc1982000, 0x00600000, "[i+1],D", 0 },
+{ "ldd", 0xc1980000, 0x00602000, "[1+2],D", 0 },
+{ "ldd", 0xc1180000, 0x00e0201f, "[1],g", 0 }, /* ldd [rs1+%g0],d */
+{ "ldd", 0xc1182000, 0x00e01fff, "[1],g", 0 }, /* ldd [rs1+0],d */
+{ "ldd", 0xc1182000, 0x00e00000, "[1+i],g", 0 },
+{ "ldd", 0xc1182000, 0x00e00000, "[i+1],g", 0 },
+{ "ldd", 0xc1180000, 0x00e02000, "[1+2],g", 0 },
+{ "ldd", 0xc0180000, 0x01e0201f, "[1],d", 0 }, /* ldd [rs1+%g0],d */
+{ "ldd", 0xc0182000, 0x01e01fff, "[1],d", 0 }, /* ldd [rs1+0],d */
+{ "ldd", 0xc0182000, 0x01e00000, "[1+i],d", 0 },
+{ "ldd", 0xc0182000, 0x01e00000, "[i+1],d", 0 },
+{ "ldd", 0xc0180000, 0x01e02000, "[1+2],d", 0 },
+{ "ld", 0xc1880000, 0x0070201f, "[1],C", 0 }, /* ld [rs1+%g0],d */
+{ "ld", 0xc1882000, 0x00701fff, "[1],C", 0 }, /* ld [rs1+0],d */
+{ "ld", 0xc1882000, 0x00700000, "[1+i],C", 0 },
+{ "ld", 0xc1882000, 0x00700000, "[i+1],C", 0 },
+{ "ld", 0xc1880000, 0x00702000, "[1+2],C", 0 },
+{ "ld", 0xc1800000, 0x0078201f, "[1],D", 0 }, /* ld [rs1+%g0],d */
+{ "ld", 0xc1802000, 0x00781fff, "[1],D", 0 }, /* ld [rs1+0],d */
+{ "ld", 0xc1802000, 0x00780000, "[1+i],D", 0 },
+{ "ld", 0xc1802000, 0x00780000, "[i+1],D", 0 },
+{ "ld", 0xc1800000, 0x00782000, "[1+2],D", 0 },
+{ "ld", 0xc1080000, 0x00f0201f, "[1],F", 0 }, /* ld [rs1+%g0],d */
+{ "ld", 0xc1082000, 0x00f01fff, "[1],F", 0 }, /* ld [rs1+0],d */
+{ "ld", 0xc1082000, 0x00f00000, "[1+i],F", 0 },
+{ "ld", 0xc1082000, 0x00f00000, "[i+1],F", 0 },
+{ "ld", 0xc1080000, 0x00f02000, "[1+2],F", 0 },
+{ "ld", 0xc1000000, 0x00f8201f, "[1],g", 0 }, /* ld [rs1+%g0],d */
+{ "ld", 0xc1002000, 0x00f81fff, "[1],g", 0 }, /* ld [rs1+0],d */
+{ "ld", 0xc1002000, 0x00f80000, "[1+i],g", 0 },
+{ "ld", 0xc1002000, 0x00f80000, "[i+1],g", 0 },
+{ "ld", 0xc1000000, 0x00f82000, "[1+2],g", 0 },
+{ "ld", 0xc0000000, 0x01f8201f, "[1],d", 0 }, /* ld [rs1+%g0],d */
+{ "ld", 0xc0002000, 0x01f81fff, "[1],d", 0 }, /* ld [rs1+0],d */
+{ "ld", 0xc0002000, 0x01f80000, "[1+i],d", 0 },
+{ "ld", 0xc0002000, 0x01f80000, "[i+1],d", 0 },
+{ "ld", 0xc0000000, 0x01f82000, "[1+2],d", 0 },
+{ "ldstuba", 0xc0d80000, 0x0100201f, "[1]A,d", 0 }, /* ldstuba [rs1+%g0],d */
+{ "ldstuba", 0xc0d80000, 0x01002000, "[1+2]A,d", 0 },
+{ "ldsha", 0xc0d00000, 0x0128201f, "[1]A,d", 0 }, /* ldsha [rs1+%g0],d */
+{ "ldsha", 0xc0d00000, 0x01282000, "[1+2]A,d", 0 },
+{ "ldsba", 0xc0c80000, 0x0130201f, "[1]A,d", 0 }, /* ldsba [rs1+%g0],d */
+{ "ldsba", 0xc0c80000, 0x01302000, "[1+2]A,d", 0 },
+{ "ldda", 0xc0980000, 0x0160201f, "[1]A,d", 0 }, /* ldda [rs1+%g0],d */
+{ "ldda", 0xc0980000, 0x01602000, "[1+2]A,d", 0 },
+{ "lduha", 0xc0900000, 0x0168201f, "[1]A,d", 0 }, /* lduha [rs1+%g0],d */
+{ "lduha", 0xc0900000, 0x01682000, "[1+2]A,d", 0 },
+{ "ldstub", 0xc0680000, 0x0190201f, "[1],d", 0 }, /* ldstub [rs1+%g0],d */
+{ "ldstub", 0xc0682000, 0x01900000, "[1+i],d", 0 },
+{ "ldstub", 0xc0682000, 0x01900000, "[i+1],d", 0 },
+{ "ldstub", 0xc0680000, 0x01902000, "[1+2],d", 0 },
+{ "lda", 0xc0800000, 0x0178201f, "[1]A,d", 0 }, /* lda [rs1+%g0],d */
+{ "lda", 0xc0800000, 0x01782000, "[1+2]A,d", 0 },
+{ "ldsh", 0xc0500000, 0x0000000d, "[1],d", 0 }, /* ldsh [rs1+%g0],d */
+{ "ldsh", 0xc0502000, 0x01a81fff, "[1],d", 0 }, /* ldsh [rs1+0],d */
+{ "ldsh", 0xc0502000, 0x01a80000, "[1+i],d", 0 },
+{ "ldsh", 0xc0502000, 0x01a80000, "[i+1],d", 0 },
+{ "ldsh", 0xc0500000, 0x01a82000, "[1+2],d", 0 },
+{ "ldsb", 0xc0480000, 0x01b0201f, "[1],d", 0 }, /* ldsb [rs1+%g0],d */
+{ "ldsb", 0xc0482000, 0x01b01fff, "[1],d", 0 }, /* ldsb [rs1+0],d */
+{ "ldsb", 0xc0482000, 0x01b00000, "[1+i],d", 0 },
+{ "ldsb", 0xc0482000, 0x01b00000, "[i+1],d", 0 },
+{ "ldsb", 0xc0480000, 0x01b02000, "[1+2],d", 0 },
+{ "ldub", 0xc0080000, 0x01f0201f, "[1],d", 0 }, /* ldub [rs1+%g0],d */
+{ "ldub", 0xc0082000, 0x01f01fff, "[1],d", 0 }, /* ldub [rs1+0],d */
+{ "ldub", 0xc0082000, 0x01f00000, "[1+i],d", 0 },
+{ "ldub", 0xc0082000, 0x01f00000, "[i+1],d", 0 },
+{ "ldub", 0xc0080000, 0x01f02000, "[1+2],d", 0 },
+{ "lduba", 0xc0880000, 0x0170201f, "[1]A,d", 0 }, /* lduba [rs1+%g0],d */
+{ "lduba", 0xc0880000, 0x01702000, "[1+2]A,d", 0 },
+{ "lduh", 0xc0102000, 0x01e80000, "[1+i],d", 0 },
+{ "lduh", 0xc0102000, 0x01e80000, "[i+1],d", 0 },
+{ "lduh", 0xc0100000, 0x01e8201f, "[1],d", 0 }, /* lduh [rs1+%g0],d */
+{ "lduh", 0xc0102000, 0x01e81fff, "[1],d", 0 }, /* lduh [rs1+0],d */
+{ "lduh", 0xc0100000, 0x01e82000, "[1+2],d", 0 },
+
+{ "st", 0xc0200000, 0x01d8201f, "d,[1]", 0 }, /* st d,[rs1+%g0] */
+{ "st", 0xc0202000, 0x01d81fff, "d,[1]", 0 }, /* st d,[rs1+0] */
+{ "st", 0xc0202000, 0x01d80000, "d,[1+i]", 0 },
+{ "st", 0xc0202000, 0x01d80000, "d,[i+1]", 0 },
+{ "st", 0xc0200000, 0x01d82000, "d,[1+2]", 0 },
+{ "st", 0xc1200000, 0x00d8201f, "g,[1]", 0 }, /* st d[rs1+%g0] */
+{ "st", 0xc1202000, 0x00d81fff, "g,[1]", 0 }, /* st d,[rs1+0] */
+{ "st", 0xc1202000, 0x00d80000, "g,[1+i]", 0 },
+{ "st", 0xc1202000, 0x00d80000, "g,[i+1]", 0 },
+{ "st", 0xc1200000, 0x00d82000, "g,[1+2]", 0 },
+{ "st", 0xc1280000, 0x00c0d01f, "F,[1]", 0 }, /* st d,[rs1+%g0] */
+{ "st", 0xc1282000, 0x00c0dfff, "F,[1]", 0 }, /* st d,[rs1+0] */
+{ "st", 0xc1282000, 0x00c0d000, "F,[1+i]", 0 },
+{ "st", 0xc1282000, 0x00c0d000, "F,[i+1]", 0 },
+{ "st", 0xc1280000, 0x00c0d000, "F,[1+2]", 0 },
+{ "st", 0xc1a00000, 0x0058201f, "D,[1]", 0 }, /* st d,[rs1+%g0] */
+{ "st", 0xc1a02000, 0x00581fff, "D,[1]", 0 }, /* st d,[rs1+0] */
+{ "st", 0xc1a02000, 0x00580000, "D,[1+i]", 0 },
+{ "st", 0xc1a02000, 0x00580000, "D,[i+1]", 0 },
+{ "st", 0xc1a00000, 0x00582000, "D,[1+2]", 0 },
+{ "st", 0xc1a80000, 0x0050201f, "C,[1]", 0 }, /* st d,[rs1+%g0] */
+{ "st", 0xc1a82000, 0x00501fff, "C,[1]", 0 }, /* st d,[rs1+0] */
+{ "st", 0xc1a82000, 0x00500000, "C,[1+i]", 0 },
+{ "st", 0xc1a82000, 0x00500000, "C,[i+1]", 0 },
+{ "st", 0xc1a80000, 0x00502000, "C,[1+2]", 0 },
+{ "sta", 0xc0a00000, 0x0108201f, "d,[1]A", 0 }, /* sta d,[rs1+%g0] */
+{ "sta", 0xc0a00000, 0x01082000, "d,[1+2]A", 0 },
+
+{ "stb", 0xc0280000, 0x01d0201f, "d,[1]", 0 }, /* stb d,[rs1+%g0] */
+{ "stb", 0xc0282000, 0x01d01fff, "d,[1]", 0 }, /* stb d,[rs1+0] */
+{ "stb", 0xc0282000, 0x01d00000, "d,[1+i]", 0 },
+{ "stb", 0xc0282000, 0x01d00000, "d,[i+1]", 0 },
+{ "stb", 0xc0280000, 0x01d02000, "d,[1+2]", 0 },
+{ "stba", 0xc0a80000, 0x01002000, "d,[1+2]A", 0 },
+{ "stba", 0xc0a80000, 0x0100201f, "d,[1]A", 0 }, /* stba d,[rs1+%g0] */
+
+{ "std", 0xc0380000, 0x01c0201f, "d,[1]", 0 }, /* std d,[rs1+%g0] */
+{ "std", 0xc0382000, 0x01c01fff, "d,[1]", 0 }, /* std d,[rs1+0] */
+{ "std", 0xc0382000, 0x01c00000, "d,[1+i]", 0 },
+{ "std", 0xc0382000, 0x01c00000, "d,[i+1]", 0 },
+{ "std", 0xc0380000, 0x01c02000, "d,[1+2]", 0 },
+{ "std", 0xc1380000, 0x00c0201f, "g,[1]", 0 }, /* std d,[rs1+%g0] */
+{ "std", 0xc1382000, 0x00c01fff, "g,[1]", 0 }, /* std d,[rs1+0] */
+{ "std", 0xc1382000, 0x00c00000, "g,[1+i]", 0 },
+{ "std", 0xc1382000, 0x00c00000, "g,[i+1]", 0 },
+{ "std", 0xc1380000, 0x00c02000, "g,[1+2]", 0 },
+{ "std", 0xc1300000, 0x00c8201f, "q,[1]", 0 }, /* std d,[rs1+%g0] */
+{ "std", 0xc1302000, 0x00c81fff, "q,[1]", 0 }, /* std d,[rs1+0] */
+{ "std", 0xc1302000, 0x00c80000, "q,[1+i]", 0 },
+{ "std", 0xc1302000, 0x00c80000, "q,[i+1]", 0 },
+{ "std", 0xc1300000, 0x00c82000, "q,[1+2]", 0 },
+{ "std", 0xc1b80000, 0x0040201f, "D,[1]", 0 }, /* std d,[rs1+%g0] */
+{ "std", 0xc1b82000, 0x00401fff, "D,[1]", 0 }, /* std d,[rs1+0] */
+{ "std", 0xc1b82000, 0x00400000, "D,[1+i]", 0 },
+{ "std", 0xc1b82000, 0x00400000, "D,[i+1]", 0 },
+{ "std", 0xc1b80000, 0x00402000, "D,[1+2]", 0 },
+{ "std", 0xc1b00000, 0x0048201f, "Q,[1]", 0 }, /* std d,[rs1+%g0] */
+{ "std", 0xc1b02000, 0x00481fff, "Q,[1]", 0 }, /* std d,[rs1+0] */
+{ "std", 0xc1b02000, 0x00480000, "Q,[1+i]", 0 },
+{ "std", 0xc1b02000, 0x00480000, "Q,[i+1]", 0 },
+{ "std", 0xc1b00000, 0x00482000, "Q,[1+2]", 0 },
+{ "stda", 0xc0b80000, 0x01402000, "d,[1+2]A", 0 },
+{ "stda", 0xc0b80000, 0x0140201f, "d,[1]A", 0 }, /* stda d,[rs1+%g0] */
+
+{ "sth", 0xc0300000, 0x01c8201f, "d,[1]", 0 }, /* sth d,[rs1+%g0] */
+{ "sth", 0xc0302000, 0x01c81fff, "d,[1]", 0 }, /* sth d,[rs1+0] */
+{ "sth", 0xc0300000, 0x01c82000, "d,[1+2]", 0 },
+{ "sth", 0xc0302000, 0x01c80000, "d,[1+i]", 0 },
+{ "sth", 0xc0302000, 0x01c80000, "d,[i+1]", 0 },
+{ "stha", 0xc0b00000, 0x0148201f, "d,[1]A", 0 }, /* stha d,[rs1+%g0] */
+{ "stha", 0xc0b00000, 0x01482000, "d,[1+2]A", 0 },
+
+{ "swap", 0xc0780000, 0x0180201f, "[1],d", 0 }, /* swap [rs1+%g0],d */
+{ "swap", 0xc0782000, 0x01801fff, "[1],d", 0 }, /* swap [rs1+0],d */
+{ "swap", 0xc0782000, 0x01800000, "[1+i],d", 0 },
+{ "swap", 0xc0782000, 0x01800000, "[i+1],d", 0 },
+{ "swap", 0xc0780000, 0x01802000, "[1+2],d", 0 },
+{ "swapa", 0xc0f80000, 0x01002000, "[1+2]A,d", 0 },
+{ "swapa", 0xc0f80000, 0x0100201f, "[1]A,d", 0 }, /* swapa [rs1+%g0],d */
+
+{ "restore", 0x81e80000, 0x7e17e01f, "", 0 }, /* restore %g0,%g0,%g0 */
+{ "restore", 0x81e82000, 0x7e14dfff, "", 0 }, /* restore %g0,0,%g0 */
+{ "restore", 0x81e82000, 0x00000000, "1,i,d", 0 },
+{ "restore", 0x81e80000, 0x00000000, "1,2,d", 0 },
+{ "rett", 0x81c82000, 0x40300000, "1+i", 1 },
+{ "rett", 0x81c82000, 0x40300000, "i+1", 1 },
+{ "rett", 0x81c80000, 0x40302000, "1+2", 1 },
+{ "rett", 0x81c82000, 0x40300000, "1", 1},
+{ "save", 0x81e02000, 0x40180000, "1,i,d", 0 },
+{ "save", 0x81e00000, 0x40180000, "1,2,d", 0 },
+
+{ "ret", 0x81c7e008, 0x00001ff7, "", 1 }, /* jmpl %i7+8,%g0 */
+{ "retl", 0x81c3e008, 0x00001ff7, "", 1 }, /* jmpl %o7+8,%g0 */
+
+{ "jmpl", 0x81c00000, 0x4038201f, "1,d", 1 }, /* jmpl rs1+%g0,d */
+{ "jmpl", 0x81c02000, 0x4037c000, "i,d", 1 }, /* jmpl %g0+i,d */
+{ "jmpl", 0x81c02000, 0x40380000, "1+i,d", 1 },
+{ "jmpl", 0x81c02000, 0x40380000, "i+1,d", 1 },
+{ "jmpl", 0x81c00000, 0x40382000, "1+2,d", 1 },
+{ "wr", 0x81982000, 0x40600000, "1,i,t", 0 },
+{ "wr", 0x81980000, 0x40600000, "1,2,t", 0 },
+{ "wr", 0x81902000, 0x40680000, "1,i,w", 0 },
+{ "wr", 0x81900000, 0x40680000, "1,2,w", 0 },
+{ "wr", 0x81882000, 0x40700000, "1,i,p", 0 },
+{ "wr", 0x81880000, 0x40700000, "1,2,p", 0 },
+{ "wr", 0x81802000, 0x40780000, "1,i,y", 0 },
+{ "wr", 0x81800000, 0x40780000, "1,2,y", 0 },
+
+{ "rd", 0x81580000, 0x40a00000, "t,d", 0 },
+{ "rd", 0x81500000, 0x40a80000, "w,d", 0 },
+{ "rd", 0x81480000, 0x40b00000, "p,d", 0 },
+{ "rd", 0x81400000, 0x40b80000, "y,d", 0 },
+
+{ "sra", 0x81382000, 0x00000000, "1,i,d", 0 },
+{ "sra", 0x81380000, 0x00000000, "1,2,d", 0 },
+{ "srl", 0x81302000, 0x40c80000, "1,i,d", 0 },
+{ "srl", 0x81300000, 0x40c80000, "1,2,d", 0 },
+{ "sll", 0x81282000, 0x40d00000, "1,i,d", 0 },
+{ "sll", 0x81280000, 0x40d00000, "1,2,d", 0 },
+
+{ "mulscc", 0x81202000, 0x40d80000, "1,i,d", 0 },
+{ "mulscc", 0x81200000, 0x40d80000, "1,2,d", 0 },
+
+{ "clr", 0x80100000, 0x4e87e01f, "d", 0 }, /* or %g0,%g0,d */
+{ "clr", 0x80102000, 0x41efdfff, "d", 0 }, /* or %g0,0,d */
+
+{ "orncc", 0x80b02000, 0x04048000, "1,i,d", 0 },
+{ "orncc", 0x80b02000, 0x04048000, "i,1,d", 0 },
+{ "orncc", 0x80b00000, 0x04048000, "1,2,d", 0 },
+
+{ "tst", 0x80900000, 0x7f6fe000, "2", 0 }, /* orcc %g0, rs2, %g0 */
+{ "tst", 0x80900000, 0x7f68201f, "1", 0 }, /* orcc rs1, %g0, %g0 */
+{ "tst", 0x80902000, 0x7f681fff, "1", 0 }, /* orcc rs1, 0, %g0 */
+
+{ "orcc", 0x80902000, 0x41680000, "1,i,d", 0 },
+{ "orcc", 0x80902000, 0x41680000, "i,1,d", 0 },
+{ "orcc", 0x80900000, 0x41680000, "1,2,d", 0 },
+{ "orn", 0x80302000, 0x41c80000, "1,i,d", 0 },
+{ "orn", 0x80302000, 0x41c80000, "i,1,d", 0 },
+{ "orn", 0x80300000, 0x41c80000, "1,2,d", 0 },
+
+{ "mov", 0x81800000, 0x4078201f, "1,y", 0 }, /* wr rs1,%g0,%y */
+{ "mov", 0x81802000, 0x40781fff, "1,y", 0 }, /* wr rs1,0,%y */
+{ "mov", 0x81400000, 0x40b80000, "y,d", 0 }, /* rd %y,d */
+{ "mov", 0x81980000, 0x4060201f, "1,t", 0 }, /* wr rs1,%g0,%tbr */
+{ "mov", 0x81982000, 0x40601fff, "1,t", 0 }, /* wr rs1,0,%tbr */
+{ "mov", 0x81580000, 0x40a00000, "t,d", 0 }, /* rd %tbr,d */
+{ "mov", 0x81900000, 0x4068201f, "1,w", 0 }, /* wr rs1,%g0,%wim */
+{ "mov", 0x81902000, 0x40681fff, "1,w", 0 }, /* wr rs1,0,%wim */
+{ "mov", 0x81500000, 0x40a80000, "w,d", 0 }, /* rd %wim,d */
+{ "mov", 0x81880000, 0x4070201f, "1,p", 0 }, /* wr rs1,%g0,%psr */
+{ "mov", 0x81882000, 0x40701fff, "1,p", 0 }, /* wr rs1,0,%psr */
+{ "mov", 0x81480000, 0x40b00000, "p,d", 0 }, /* rd %psr,d */
+
+{ "mov", 0x80102000, 0x41efc000, "i,d", 0 }, /* or %g0,i,d */
+{ "mov", 0x80100000, 0x41efe000, "2,d", 0 }, /* or %g0,rs2,d */
+
+{ "or", 0x80102000, 0x40800000, "1,i,d", 0 },
+{ "or", 0x80102000, 0x40800000, "i,1,d", 0 },
+{ "or", 0x80100000, 0x40800000, "1,2,d", 0 },
+
+{ "andncc", 0x80a82000, 0x41500000, "1,i,d", 0 },
+{ "andncc", 0x80a82000, 0x41500000, "i,1,d", 0 },
+{ "andncc", 0x80a80000, 0x41500000, "1,2,d", 0 },
+{ "andn", 0x80282000, 0x41d00000, "1,i,d", 0 },
+{ "andn", 0x80282000, 0x41d00000, "i,1,d", 0 },
+{ "andn", 0x80280000, 0x41d00000, "1,2,d", 0 },
+
+{ "cmp", 0x80a02000, 0x7d580000, "1,i", 0 }, /* subcc rs1,i,%g0 */
+{ "cmp", 0x80a00000, 0x7d580000, "1,2", 0 }, /* subcc rs1,rs2,%g0 */
+
+{ "subcc", 0x80a02000, 0x41580000, "1,i,d", 0 },
+{ "subcc", 0x80a00000, 0x41580000, "1,2,d", 0 },
+{ "sub", 0x80202000, 0x41d80000, "1,i,d", 0 },
+{ "sub", 0x80200000, 0x41d80000, "1,2,d", 0 },
+{ "subx", 0x80602000, 0x41980000, "1,i,d", 0 },
+{ "subx", 0x80600000, 0x41980000, "1,2,d", 0 },
+{ "subxcc", 0x80e02000, 0x41180000, "1,i,d", 0 },
+{ "subxcc", 0x80e00000, 0x41180000, "1,2,d", 0 },
+
+{ "andcc", 0x80882000, 0x41700000, "1,i,d", 0 },
+{ "andcc", 0x80882000, 0x41700000, "i,1,d", 0 },
+{ "andcc", 0x80880000, 0x41700000, "1,2,d", 0 },
+{ "and", 0x80082000, 0x41f00000, "1,i,d", 0 },
+{ "and", 0x80082000, 0x41f00000, "i,1,d", 0 },
+{ "and", 0x80080000, 0x41f00000, "1,2,d", 0 },
+
+{ "inc", 0x80002001, 0x41f81ffe, "r", 0 }, /* add rs1,1,rsd */
+
+{ "addxcc", 0x80c02000, 0x41380000, "1,i,d", 0 },
+{ "addxcc", 0x80c02000, 0x41380000, "i,1,d", 0 },
+{ "addxcc", 0x80c00000, 0x41380000, "1,2,d", 0 },
+{ "addcc", 0x80802000, 0x41780000, "1,i,d", 0 },
+{ "addcc", 0x80802000, 0x41780000, "i,1,d", 0 },
+{ "addcc", 0x80800000, 0x41780000, "1,2,d", 0 },
+{ "addx", 0x80402000, 0x41b80000, "1,i,d", 0 },
+{ "addx", 0x80402000, 0x41b80000, "i,1,d", 0 },
+{ "addx", 0x80400000, 0x41b80000, "1,2,d", 0 },
+{ "add", 0x80002000, 0x41f80000, "1,i,d", 0 },
+{ "add", 0x80002000, 0x41f80000, "i,1,d", 0 },
+{ "add", 0x80000000, 0x41f80000, "1,2,d", 0 },
+
+{ "call", 0x9fc00000, 0x4038201f, "1", 1 }, /* jmpl rs1+%g0, %o7 */
+{ "call", 0x9fc00000, 0x4038201f, "1,#", 1 },
+{ "call", 0x40000000, 0x80000000, "L", 1 },
+{ "call", 0x40000000, 0x80000000, "L,#", 1 },
+
+{ "bvc", 0x3e800000, 0xc1400000, ",al", 1 },
+{ "bvc", 0x1e800000, 0xc1400000, "l", 1 },
+{ "bvs", 0x2e800000, 0xc1400000, ",al", 1 },
+{ "bvs", 0x0e800000, 0xc1400000, "l", 1 },
+{ "bpos", 0x3c800000, 0xc1400000, ",al", 1 },
+{ "bpos", 0x1c800000, 0xc1400000, "l", 1 },
+{ "bneg", 0x2c800000, 0xc1400000, ",al", 1 },
+{ "bneg", 0x0c800000, 0xc1400000, "l", 1 },
+{ "bcc", 0x3a800000, 0xc1400000, ",al", 1 },
+{ "bcc", 0x1a800000, 0xc1400000, "l", 1 },
+{ "bcs", 0x2a800000, 0xc1400000, ",al", 1 },
+{ "bcs", 0x0a800000, 0xc1400000, "l", 1 },
+{ "blu", 0x2a800000, 0xc1400000, ",al", 1 },
+{ "blu", 0x0a800000, 0xc1400000, "l", 1 }, /* same as bcs */
+{ "bgeu", 0x3a800000, 0xc1400000, ",al", 1 },
+{ "bgeu", 0x1a800000, 0xc1400000, "l", 1 }, /* same as bcc */
+{ "bgu", 0x38800000, 0xc1400000, ",al", 1 },
+{ "bgu", 0x18800000, 0xc1400000, "l", 1 },
+{ "bleu", 0x28800000, 0xc1400000, ",al", 1 },
+{ "bleu", 0x08800000, 0xc1400000, "l", 1 },
+{ "bge", 0x36800000, 0xc1400000, ",al", 1 },
+{ "bge", 0x16800000, 0xc1400000, "l", 1 },
+{ "bl", 0x26800000, 0xc1400000, ",al", 1 },
+{ "bl", 0x06800000, 0xc1400000, "l", 1 },
+{ "bg", 0x34800000, 0xc1400000, ",al", 1 },
+{ "bg", 0x14800000, 0xc1400000, "l", 1 },
+{ "ble", 0x24800000, 0xc1400000, ",al", 1 },
+{ "ble", 0x04800000, 0xc1400000, "l", 1 },
+{ "be", 0x22800000, 0xc1400000, ",al", 1 },
+{ "be", 0x02800000, 0xc1400000, "l", 1 },
+{ "bne", 0x32800000, 0xc1400000, ",al", 1 },
+{ "bne", 0x12800000, 0xc1400000, "l", 1 },
+{ "b", 0x30800000, 0xc1400000, ",al", 1 },
+{ "b", 0x10800000, 0xc1400000, "l", 1 },
+{ "ba", 0x30800000, 0xc1400000, ",al", 1 },
+{ "ba", 0x10800000, 0xc1400000, "l", 1 },
+{ "bn", 0x20800000, 0xc1400000, ",al", 1 },
+{ "bn", 0x00800000, 0xc1400000, "l", 1 },
+
+{ "jmp", 0x81c00000, 0x7e38201f, "1", 1 }, /* jmpl rs1+%g0,%g0 */
+{ "jmp", 0x81c02000, 0x7e3fc000, "i", 1 }, /* jmpl %g0+i,%g0 */
+{ "jmp", 0x81c00000, 0x7e382000, "1+2", 1 }, /* jmpl rs1+rs2,%g0 */
+{ "jmp", 0x81c02000, 0x7e380000, "1+i", 1 }, /* jmpl rs1+i,%g0 */
+{ "jmp", 0x81c02000, 0x7e380000, "i+1", 1 }, /* jmpl i+rs1,%g0 */
+
+{ "nop", 0x01000000, 0xfe3fffff, "", 0 }, /* sethi 0, %g0 */
+
+{ "set", 0x01000000, 0xc0c00000, "Sh,d", 0 },
+
+{ "sethi", 0x01000000, 0xc0c00000, "h,d", 0 },
+
+{ "taddcctv", 0x81102000, 0x40e00000, "1,i,d", 0 },
+{ "taddcctv", 0x81100000, 0x40e00000, "1,2,d", 0 },
+{ "taddcc", 0x81002000, 0x40f80000, "1,i,d", 0 },
+{ "taddcc", 0x81000000, 0x40f80000, "1,2,d", 0 },
+
+{ "tvc", 0x9fd02000, 0x402fc000, "i", 0 }, /* tvc %g0+i */
+{ "tvc", 0x9fd02000, 0x40280000, "1+i", 0 },
+{ "tvc", 0x9fd00000, 0x40282000, "1+2", 0 },
+{ "tvc", 0x9fd00000, 0x4028201f, "1", 0 }, /* tvc rs1+%g0 */
+{ "tpos", 0x9dd02000, 0x402fc000, "i", 0 }, /* tpos %g0+i */
+{ "tpos", 0x9dd02000, 0x40280000, "1+i", 0 },
+{ "tpos", 0x9dd00000, 0x40282000, "1+2", 0 },
+{ "tpos", 0x9dd00000, 0x4028201f, "1", 0 }, /* tpos rs1+%g0 */
+{ "tcc", 0x9bd02000, 0x402fc000, "i", 0 }, /* tcc %g0+i */
+{ "tcc", 0x9bd02000, 0x40280000, "1+i", 0 },
+{ "tcc", 0x9bd00000, 0x40282000, "1+2", 0 },
+{ "tcc", 0x9bd00000, 0x4028201f, "1", 0 }, /* tcc rs1+%g0 */
+{ "tgu", 0x99d02000, 0x402fc000, "i", 0 }, /* tgu %g0+i */
+{ "tgu", 0x99d02000, 0x40280000, "1+i", 0 },
+{ "tgu", 0x99d00000, 0x40282000, "1+2", 0 },
+{ "tgu", 0x99d00000, 0x4028201f, "1", 0 }, /* tgu rs1+%g0 */
+{ "tge", 0x97d02000, 0x402fc000, "i", 0 }, /* tge %g0+i */
+{ "tge", 0x97d02000, 0x40280000, "1+i", 0 },
+{ "tge", 0x97d00000, 0x40282000, "1+2", 0 },
+{ "tge", 0x97d00000, 0x4028201f, "1", 0 }, /* tge rs1+%g0 */
+{ "tg", 0x95d02000, 0x402fc000, "i", 0 }, /* tg %g0+i */
+{ "tg", 0x95d02000, 0x40280000, "1+i", 0 },
+{ "tg", 0x95d00000, 0x40282000, "1+2", 0 },
+{ "tg", 0x95d00000, 0x4028201f, "1", 0 }, /* tg rs1+%g0 */
+{ "tne", 0x93d02000, 0x402fc000, "i", 0 }, /* tne %g0+i */
+{ "tne", 0x93d02000, 0x40280000, "1+i", 0 },
+{ "tne", 0x93d00000, 0x40282000, "1+2", 0 },
+{ "tne", 0x93d00000, 0x4028201f, "1", 0 }, /* tne rs1+%g0 */
+{ "tleu", 0x8bd02000, 0x502fc000, "i", 0 }, /* tleu %g0+i */
+{ "tleu", 0x8bd02000, 0x50280000, "1+i", 0 },
+{ "tleu", 0x8bd00000, 0x50282000, "1+2", 0 },
+{ "tleu", 0x8bd00000, 0x5028201f, "1", 0 }, /* tleu rs1+%g0 */
+{ "ta", 0x91d02000, 0x402fc000, "i", 0 }, /* ta %g0+i */
+{ "ta", 0x91d02000, 0x402d0000, "1+i", 0 },
+{ "ta", 0x91d00000, 0x40282000, "1+2", 0 },
+{ "ta", 0x91d00000, 0x4028201f, "1", 0 }, /* ta rs1+%g0 */
+{ "tvs", 0x8fd02000, 0x502fc000, "i", 0 }, /* tvs %g0+i */
+{ "tvs", 0x8fd02000, 0x50280000, "1+i", 0 },
+{ "tvs", 0x8fd00000, 0x50282000, "1+2", 0 },
+{ "tvs", 0x8fd00000, 0x5028201f, "1", 0 }, /* tvs rs1+%g0 */
+{ "tneg", 0x8dd02000, 0x502fc000, "i", 0 }, /* tneg %g0+i */
+{ "tneg", 0x8dd02000, 0x50280000, "1+i", 0 },
+{ "tneg", 0x8dd00000, 0x50282000, "1+2", 0 },
+{ "tneg", 0x8dd00000, 0x5028201f, "1", 0 }, /* tneg rs1+%g0 */
+{ "tcs", 0x8bd02000, 0x502fc000, "i", 0 }, /* tcs %g0+i */
+{ "tcs", 0x8bd02000, 0x50280000, "1+i", 0 },
+{ "tcs", 0x8bd00000, 0x50282000, "1+2", 0 },
+{ "tcs", 0x8bd00000, 0x5028201f, "1", 0 }, /* tcs rs1+%g0 */
+{ "tl", 0x87d02000, 0x502fc000, "i", 0 }, /* tl %g0+i */
+{ "tl", 0x87d02000, 0x50280000, "1+i", 0 },
+{ "tl", 0x87d00000, 0x50282000, "1+2", 0 },
+{ "tl", 0x87d00000, 0x5028201f, "1", 0 }, /* tl rs1+%g0 */
+{ "tle", 0x85d02000, 0x502fc000, "i", 0 }, /* tle %g0+i */
+{ "tle", 0x85d02000, 0x50280000, "1+i", 0 },
+{ "tle", 0x85d00000, 0x50282000, "1+2", 0 },
+{ "tle", 0x85d00000, 0x5028201f, "1", 0 }, /* tle rs1+%g0 */
+{ "te", 0x83d02000, 0x502fc000, "i", 0 }, /* te %g0+i */
+{ "te", 0x83d02000, 0x50280000, "1+i", 0 },
+{ "te", 0x83d00000, 0x50282000, "1+2", 0 },
+{ "te", 0x83d00000, 0x5028201f, "1", 0 }, /* te rs1+%g0 */
+{ "tn", 0x81d02000, 0x502fc000, "i", 0 }, /* tn %g0+i */
+{ "tn", 0x81d02000, 0x50280000, "1+i", 0 },
+{ "tn", 0x81d00000, 0x50282000, "1+2", 0 },
+{ "tn", 0x81d00000, 0x5028201f, "1", 0 }, /* tn rs1+%g0 */
+
+{ "tsubcc", 0x81080000, 0x40f00000, "1,2,d", 0 },
+{ "tsubcc", 0x81082000, 0x40f00000, "1,i,d", 0 },
+{ "tsubcctv", 0x80580000, 0x40a00000, "1,2,d", 0 },
+{ "tsubcctv", 0x80582000, 0x40a00000, "1,i,d", 0 },
+
+{ "unimp", 0x00000000, 0x00000000, "l", 0 },
+
+{ "iflush", 0x81d80000, 0x40202000, "1+2", 0 },
+{ "iflush", 0x81d82000, 0x40200000, "1+i", 0 },
+
+{ "xnorcc", 0x80b80000, 0x41400000, "1,2,d", 0 },
+{ "xnorcc", 0x80b82000, 0x41400000, "1,i,d", 0 },
+{ "xnorcc", 0x80b82000, 0x41400000, "i,1,d", 0 },
+{ "xorcc", 0x80980000, 0x41600000, "1,2,d", 0 },
+{ "xorcc", 0x80982000, 0x41600000, "1,i,d", 0 },
+{ "xorcc", 0x80982000, 0x41600000, "i,1,d", 0 },
+{ "xnor", 0x80380000, 0x41c00000, "1,2,d", 0 },
+{ "xnor", 0x80382000, 0x41c00000, "1,i,d", 0 },
+{ "xnor", 0x80382000, 0x41c00000, "i,1,d", 0 },
+{ "xor", 0x80180000, 0x41e00000, "1,2,d", 0 },
+{ "xor", 0x80182000, 0x41e00000, "1,i,d", 0 },
+{ "xor", 0x80182000, 0x41e00000, "i,1,d", 0 },
+
+{ "fpop1", 0x81a00000, 0x40580000, "[1+2],d", 0 },
+{ "fpop2", 0x81a80000, 0x40500000, "[1+2],d", 0 },
+
+{ "fb", 0x31800000, 0xc0400000, ",al", 1 },
+{ "fb", 0x11800000, 0xc0400000, "l", 1 },
+{ "fba", 0x31800000, 0xc0400000, ",al", 1 },
+{ "fba", 0x11800000, 0xc0400000, "l", 1 },
+{ "fbn", 0x21800000, 0xc0400000, ",al", 1 },
+{ "fbn", 0x01800000, 0xc0400000, "l", 1 },
+{ "fbu", 0x2f800000, 0xc0400000, ",al", 1 },
+{ "fbu", 0x0f800000, 0xc0400000, "l", 1 },
+{ "fbg", 0x2d800000, 0xc0400000, ",al", 1 },
+{ "fbg", 0x0d800000, 0xc0400000, "l", 1 },
+{ "fbug", 0x2b800000, 0xc0400000, ",al", 1 },
+{ "fbug", 0x0b800000, 0xc0400000, "l", 1 },
+{ "fbl", 0x29800000, 0xc0400000, ",al", 1 },
+{ "fbl", 0x09800000, 0xc0400000, "l", 1 },
+{ "fbul", 0x27800000, 0xc0400000, ",al", 1 },
+{ "fbul", 0x07800000, 0xc0400000, "l", 1 },
+{ "fblg", 0x25800000, 0xc0400000, ",al", 1 },
+{ "fblg", 0x05800000, 0xc0400000, "l", 1 },
+{ "fbne", 0x23800000, 0xc0400000, ",al", 1 },
+{ "fbne", 0x03800000, 0xc0400000, "l", 1 },
+{ "fbe", 0x33800000, 0xc0400000, ",al", 1 },
+{ "fbe", 0x13800000, 0xc0400000, "l", 1 },
+{ "fbue", 0x35800000, 0xc0400000, ",al", 1 },
+{ "fbue", 0x15800000, 0xc0400000, "l", 1 },
+{ "fbge", 0x37800000, 0xc0400000, ",al", 1 },
+{ "fbge", 0x17800000, 0xc0400000, "l", 1 },
+{ "fbuge", 0x39800000, 0xc0400000, ",al", 1 },
+{ "fbuge", 0x19800000, 0xc0400000, "l", 1 },
+{ "fble", 0x3b800000, 0xc0400000, ",al", 1 },
+{ "fble", 0x1b800000, 0xc0400000, "l", 1 },
+{ "fbule", 0x3d800000, 0xc0400000, ",al", 1 },
+{ "fbule", 0x1d800000, 0xc0400000, "l", 1 },
+{ "fbo", 0x3f800000, 0xc0400000, ",al", 1 },
+{ "fbo", 0x1f800000, 0xc0400000, "l", 1 },
+
+{ "cba", 0x31c00000, 0xce000000, ",al", 1 },
+{ "cba", 0x11c00000, 0xce000000, "l", 1 },
+{ "cbn", 0x21c00000, 0xde000000, ",al", 1 },
+{ "cbn", 0x01c00000, 0xde000000, "l", 1 },
+{ "cb3", 0x2fc00000, 0xc0000000, ",al", 1 },
+{ "cb3", 0x0fc00000, 0xc0000000, "l", 1 },
+{ "cb2", 0x2dc00000, 0xc0000000, ",al", 1 },
+{ "cb2", 0x0dc00000, 0xc0000000, "l", 1 },
+{ "cb23", 0x2bc00000, 0xc0000000, ",al", 1 },
+{ "cb23", 0x0bc00000, 0xc0000000, "l", 1 },
+{ "cb1", 0x29c00000, 0xc0000000, ",al", 1 },
+{ "cb1", 0x09c00000, 0xc0000000, "l", 1 },
+{ "cb13", 0x27c00000, 0xc0000000, ",al", 1 },
+{ "cb13", 0x07c00000, 0xc0000000, "l", 1 },
+{ "cb12", 0x25c00000, 0xc0000000, ",al", 1 },
+{ "cb12", 0x05c00000, 0xc0000000, "l", 1 },
+{ "cb123", 0x23c00000, 0xc0000000, ",al", 1 },
+{ "cb123", 0x03c00000, 0xc0000000, "l", 1 },
+{ "cb0", 0x33c00000, 0xc0000000, ",al", 1 },
+{ "cb0", 0x13c00000, 0xc0000000, "l", 1 },
+{ "cb03", 0x35c00000, 0xc0000000, ",al", 1 },
+{ "cb03", 0x15c00000, 0xc0000000, "l", 1 },
+{ "cb02", 0x37c00000, 0xc0000000, ",al", 1 },
+{ "cb02", 0x17c00000, 0xc0000000, "l", 1 },
+{ "cb023", 0x39c00000, 0xc0000000, ",al", 1 },
+{ "cb023", 0x19c00000, 0xc0000000, "l", 1 },
+{ "cb013", 0x3dc00000, 0xc0000000, ",al", 1 },
+{ "cb013", 0x1dc00000, 0xc0000000, "l", 1 },
+{ "cb012", 0x3fc00000, 0xc0000000, ",al", 1 },
+{ "cb012", 0x1fc00000, 0xc0000000, "l", 1 },
+
+{ "fstoi", 0x81a01a20, 0x400025c0, "f,g", 0 },
+{ "fdtoi", 0x81a01a40, 0x400025a0, "f,g", 0 },
+{ "fxtoi", 0x81a01a60, 0x40002580, "f,g", 0 },
+
+{ "fitox", 0x81a01980, 0x40002660, "f,g", 0 },
+{ "fitod", 0x81a01900, 0x400026e0, "f,g", 0 },
+{ "fitos", 0x81a01880, 0x40002660, "f,g", 0 },
+
+{ "fstod", 0x81a01920, 0x400026c0, "f,g", 0 },
+{ "fstox", 0x81a019a0, 0x40002640, "f,g", 0 },
+{ "fdtos", 0x81a018c0, 0x40002720, "f,g", 0 },
+{ "fdtox", 0x81a019c0, 0x40002620, "f,g", 0 },
+{ "fxtos", 0x81a018e0, 0x40002700, "f,g", 0 },
+{ "fxtod", 0x81a01960, 0x40002680, "f,g", 0 },
+
+{ "fdivx", 0x81a009e0, 0x40083600, "e,f,g", 0 },
+{ "fdivd", 0x81a009c0, 0x40003620, "e,f,g", 0 },
+{ "fdivs", 0x81a009a0, 0x40003640, "e,f,g", 0 },
+{ "fmuls", 0x81a00920, 0x400036c0, "e,f,g", 0 },
+{ "fmuld", 0x81a00940, 0x400036a0, "e,f,g", 0 },
+{ "fmulx", 0x81a00960, 0x40003680, "e,f,g", 0 },
+
+{ "fsqrts", 0x81a00520, 0x40003ac0, "f,g", 0 },
+{ "fsqrtd", 0x81a00540, 0x40003aa8, "f,g", 0 },
+{ "fsqrtx", 0x81a00560, 0x40003a80, "f,g", 0 },
+
+{ "fabss", 0x81a00120, 0x40003ec0, "f,g", 0 },
+{ "fnegs", 0x81a000a0, 0x40003f40, "f,g", 0 },
+{ "fmovs", 0x81a00020, 0x40003fc0, "f,g", 0 },
+
+{ "fsubx", 0x81a008e0, 0x40003700, "e,f,g", 0 },
+{ "fsubd", 0x81a008c0, 0x40003720, "e,f,g", 0 },
+{ "fsubs", 0x81a008a0, 0x40003740, "e,f,g", 0 },
+{ "faddx", 0x81a00860, 0x40003780, "e,f,g", 0 },
+{ "faddd", 0x81a00840, 0x400037a0, "e,f,g", 0 },
+{ "fadds", 0x81a00820, 0x400037c0, "e,f,g", 0 },
+
+{ "fcmpex", 0x81a80ae0, 0x40003500, "e,f", 0 },
+{ "fcmped", 0x81a80ac0, 0x40003520, "e,f", 0 },
+{ "fcmpes", 0x81a80aa0, 0x40003540, "e,f", 0 },
+{ "fcmpx", 0x81a80a60, 0x40003580, "e,f", 0 },
+{ "fcmpd", 0x81a80a40, 0x400035a0, "e,f", 0 },
+{ "fcmps", 0x81a80a20, 0x400035c0, "e,f", 0 },
+
+{ "cpop1", 0x81b00000, 0x40480000, "[1+2],d", 0 },
+{ "cpop2", 0x81b80000, 0x40400000, "[1+2],d", 0 },
+};
+
+#define NUMOPCODES ((sizeof sparc_opcodes)/(sizeof sparc_opcodes[0]))
+
diff --git a/gnu/usr.bin/gas/config/sparc.c b/gnu/usr.bin/gas/config/sparc.c
new file mode 100644
index 00000000000..2fbddc5e08e
--- /dev/null
+++ b/gnu/usr.bin/gas/config/sparc.c
@@ -0,0 +1,1285 @@
+/* sparc.c -- Assemble for the SPARC
+ Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+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>
+#include <ctype.h>
+
+#include "sparc-opcode.h"
+#include "as.h"
+#include "frags.h"
+#include "struc-symbol.h"
+#include "flonum.h"
+#include "expr.h"
+#include "hash.h"
+#include "md.h"
+#include "sparc.h"
+#include "write.h"
+#include "read.h"
+#include "symbols.h"
+
+void md_begin();
+void md_end();
+void md_number_to_chars();
+void md_assemble();
+char *md_atof();
+void md_convert_frag();
+void md_create_short_jump();
+void md_create_long_jump();
+int md_estimate_size_before_relax();
+void md_number_to_imm();
+void md_number_to_disp();
+void md_number_to_field();
+void md_ri_to_chars();
+void emit_relocations();
+static void sparc_ip();
+
+const relax_typeS md_relax_table[] = { 0 };
+
+/* handle of the OPCODE hash table */
+static struct hash_control *op_hash = NULL;
+
+static void s_seg(), s_proc(), s_data1(), s_reserve(), s_common();
+extern void s_globl(), s_long(), s_short(), s_space(), cons();
+
+const pseudo_typeS
+md_pseudo_table[] = {
+ { "common", s_common, 0 },
+ { "global", s_globl, 0 },
+ { "half", cons, 2 },
+ { "proc", s_proc, 0 },
+ { "reserve", s_reserve, 0 },
+ { "seg", s_seg, 0 },
+ { "skip", s_space, 0 },
+ { "word", cons, 4 },
+ { NULL, 0, 0 },
+};
+
+int md_short_jump_size = 4;
+int md_long_jump_size = 4;
+int omagic = (0x103 << 16) | OMAGIC; /* Magic number for header */
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful */
+char comment_chars[] = "!"; /* JF removed '|' from comment_chars */
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that '/*' will always start a comment */
+char line_comment_chars[] = "#";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+/* 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.
+ */
+int size_reloc_info = sizeof(struct reloc_info_sparc);
+
+static unsigned char octal[256];
+#define isoctal(c) octal[c]
+static unsigned char toHex[256];
+
+/*
+ * anull bit - causes the branch delay slot instructions to not be executed
+ */
+#define ANNUL (1 << 29)
+
+struct sparc_it {
+ char *error;
+ unsigned long opcode;
+ struct nlist *nlistp;
+ expressionS exp;
+ int pcrel;
+ enum reloc_type reloc;
+} the_insn, set_insn;
+
+#ifdef __STDC__
+#if 0
+static void print_insn(struct sparc_it *insn);
+#endif
+static int getExpression(char *str);
+#else
+#if 0
+static void print_insn();
+#endif
+static int getExpression();
+#endif
+static char *expr_end;
+static int special_case;
+
+#define SPECIAL_CASE_SET 1
+
+/*
+ * sort of like s_lcomm
+ *
+ */
+static void
+s_reserve()
+{
+ char *name;
+ char c;
+ char *p;
+ int temp;
+ symbolS *symbolP;
+
+ name = input_line_pointer;
+ c = get_symbol_end();
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE();
+ if ( * input_line_pointer != ',' ) {
+ as_warn("Expected comma after name");
+ ignore_rest_of_line();
+ return;
+ }
+ input_line_pointer ++;
+ if ((temp = get_absolute_expression()) < 0) {
+ as_warn("BSS length (%d.) <0! Ignored.", temp);
+ ignore_rest_of_line();
+ return;
+ }
+ *p = 0;
+ symbolP = symbol_find_or_make(name);
+ *p = c;
+ if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0) {
+ as_warn("bad .reserve segment: `%s'", input_line_pointer);
+ return;
+ }
+ input_line_pointer += 6;
+ if (symbolP->sy_other == 0
+ && symbolP->sy_desc == 0
+ && ((symbolP->sy_type == N_BSS
+ && symbolP->sy_value == local_bss_counter)
+ || ((symbolP->sy_type & N_TYPE) == N_UNDF
+ && symbolP->sy_value == 0))) {
+ symbolP->sy_value = local_bss_counter;
+ symbolP->sy_type = N_BSS;
+ symbolP->sy_frag = & bss_address_frag;
+ local_bss_counter += temp;
+ } else {
+ as_warn( "Ignoring attempt to re-define symbol from %d. to %d.",
+ symbolP->sy_value, local_bss_counter );
+ }
+ demand_empty_rest_of_line();
+ return;
+}
+
+static void
+s_common()
+{
+ register char *name;
+ register char c;
+ register char *p;
+ register int temp;
+ register symbolS * symbolP;
+
+ name = input_line_pointer;
+ c = get_symbol_end();
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE();
+ if ( * input_line_pointer != ',' ) {
+ as_warn("Expected comma after symbol-name");
+ ignore_rest_of_line();
+ return;
+ }
+ input_line_pointer ++; /* skip ',' */
+ if ( (temp = get_absolute_expression ()) < 0 ) {
+ as_warn(".COMMon length (%d.) <0! Ignored.", temp);
+ ignore_rest_of_line();
+ return;
+ }
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+ if ( (symbolP->sy_type & N_TYPE) != N_UNDF ||
+ symbolP->sy_other != 0 || symbolP->sy_desc != 0) {
+ as_warn( "Ignoring attempt to re-define symbol");
+ ignore_rest_of_line();
+ return;
+ }
+ if (symbolP->sy_value) {
+ if (symbolP->sy_value != temp) {
+ as_warn( "Length of .comm \"%s\" is already %d. Not changed to %d.",
+ symbolP->sy_name, symbolP->sy_value, temp);
+ }
+ } else {
+ symbolP->sy_value = temp;
+ symbolP->sy_type |= N_EXT;
+ }
+ know(symbolP->sy_frag == &zero_address_frag);
+ if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0) {
+ p=input_line_pointer;
+ while(*p && *p!='\n')
+ p++;
+ c= *p;
+ *p='\0';
+ as_warn("bad .common segment: `%s'", input_line_pointer);
+ *p=c;
+ return;
+ }
+ input_line_pointer += 6;
+ demand_empty_rest_of_line();
+ return;
+}
+
+static void
+s_seg()
+{
+
+ if (strncmp(input_line_pointer, "\"text\"", 6) == 0) {
+ input_line_pointer += 6;
+ s_text();
+ return;
+ }
+ if (strncmp(input_line_pointer, "\"data\"", 6) == 0) {
+ input_line_pointer += 6;
+ s_data();
+ return;
+ }
+ if (strncmp(input_line_pointer, "\"data1\"", 7) == 0) {
+ input_line_pointer += 7;
+ s_data1();
+ return;
+ }
+ as_warn("Unknown segment type");
+ demand_empty_rest_of_line();
+ return;
+}
+
+static void
+s_data1()
+{
+ subseg_new(SEG_DATA, 1);
+ demand_empty_rest_of_line();
+ return;
+}
+
+static void
+s_proc()
+{
+ extern char is_end_of_line[];
+
+ while (!is_end_of_line[*input_line_pointer]) {
+ ++input_line_pointer;
+ }
+ ++input_line_pointer;
+ return;
+}
+
+/* This function is called once, at assembler startup time. It should
+ set up all the tables, etc. that the MD part of the assembler will need. */
+void
+md_begin()
+{
+ register char *retval = NULL;
+ int lose = 0;
+ register unsigned int i = 0;
+
+ op_hash = hash_new();
+ if (op_hash == NULL)
+ as_fatal("Virtual memory exhausted");
+
+ while (i < NUMOPCODES)
+ {
+ const char *name = sparc_opcodes[i].name;
+ retval = hash_insert(op_hash, name, &sparc_opcodes[i]);
+ if(retval != NULL && *retval != '\0')
+ {
+ fprintf (stderr, "internal error: can't hash `%s': %s\n",
+ sparc_opcodes[i].name, retval);
+ lose = 1;
+ }
+ do
+ {
+ if (sparc_opcodes[i].match & sparc_opcodes[i].lose)
+ {
+ fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
+ sparc_opcodes[i].name, sparc_opcodes[i].args);
+ lose = 1;
+ }
+ ++i;
+ } while (i < NUMOPCODES
+ && !strcmp(sparc_opcodes[i].name, name));
+ }
+
+ if (lose)
+ as_fatal ("Broken assembler. No assembly attempted.");
+
+ for (i = '0'; i < '8'; ++i)
+ octal[i] = 1;
+ for (i = '0'; i <= '9'; ++i)
+ toHex[i] = i - '0';
+ for (i = 'a'; i <= 'f'; ++i)
+ toHex[i] = i + 10 - 'a';
+ for (i = 'A'; i <= 'F'; ++i)
+ toHex[i] = i + 10 - 'A';
+}
+
+void
+md_end()
+{
+ return;
+}
+
+void
+md_assemble(str)
+ char *str;
+{
+ char *toP;
+ int rsd;
+
+ assert(str);
+ sparc_ip(str);
+ toP = frag_more(4);
+ /* put out the opcode */
+ md_number_to_chars(toP, the_insn.opcode, 4);
+
+ /* put out the symbol-dependent stuff */
+ if (the_insn.reloc != NO_RELOC) {
+ fix_new(
+ frag_now, /* which frag */
+ (toP - frag_now->fr_literal), /* where */
+ 4, /* size */
+ the_insn.exp.X_add_symbol,
+ the_insn.exp.X_subtract_symbol,
+ the_insn.exp.X_add_number,
+ the_insn.pcrel,
+ the_insn.reloc
+ );
+ }
+ switch (special_case) {
+
+ case SPECIAL_CASE_SET:
+ special_case = 0;
+ assert(the_insn.reloc == RELOC_HI22);
+ toP = frag_more(4);
+ rsd = (the_insn.opcode >> 25) & 0x1f;
+ the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14);
+ md_number_to_chars(toP, the_insn.opcode, 4);
+ fix_new(
+ frag_now, /* which frag */
+ (toP - frag_now->fr_literal), /* where */
+ 4, /* size */
+ the_insn.exp.X_add_symbol,
+ the_insn.exp.X_subtract_symbol,
+ the_insn.exp.X_add_number,
+ the_insn.pcrel,
+ RELOC_LO10
+ );
+ return;
+
+ case 0:
+ return;
+
+ default:
+ abort();
+ }
+}
+
+static void
+sparc_ip(str)
+ char *str;
+{
+ char *s;
+ const char *args;
+ char c;
+ unsigned long i;
+ struct sparc_opcode *insn;
+ char *argsStart;
+ unsigned long opcode;
+ unsigned int mask;
+ int match = FALSE;
+ int comma = 0;
+
+ for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s)
+ ;
+ switch (*s) {
+
+ case '\0':
+ break;
+
+ case ',':
+ comma = 1;
+
+ /*FALLTHROUGH*/
+
+ case ' ':
+ *s++ = '\0';
+ break;
+
+ default:
+ as_warn("Unknown opcode: `%s'", str);
+ exit(1);
+ }
+ if ((insn = (struct sparc_opcode *) hash_find(op_hash, str)) == NULL) {
+ as_warn("Unknown opcode: `%s'", str);
+ return;
+ }
+ if (comma) {
+ *--s = ',';
+ }
+ argsStart = s;
+ for (;;) {
+ opcode = insn->match;
+ bzero(&the_insn, sizeof(the_insn));
+ the_insn.reloc = NO_RELOC;
+
+ /*
+ * Build the opcode, checking as we go to make
+ * sure that the operands match
+ */
+ for (args = insn->args; ; ++args) {
+ switch (*args) {
+
+ case '\0': /* end of args */
+ if (*s == '\0') {
+ match = TRUE;
+ }
+ break;
+
+ case '+':
+ if (*s == '+') {
+ ++s;
+ continue;
+ }
+ if (*s == '-') {
+ continue;
+ }
+ break;
+
+ case '[': /* these must match exactly */
+ case ']':
+ case ',':
+ case ' ':
+ if (*s++ == *args)
+ continue;
+ break;
+
+ case '#': /* must be at least one digit */
+ if (isdigit(*s++)) {
+ while (isdigit(*s)) {
+ ++s;
+ }
+ continue;
+ }
+ break;
+
+ case 'C': /* coprocessor state register */
+ if (strncmp(s, "%csr", 4) == 0) {
+ s += 4;
+ continue;
+ }
+ break;
+
+ case 'b': /* next operand is a coprocessor register */
+ case 'c':
+ case 'D':
+ if (*s++ == '%' && *s++ == 'c' && isdigit(*s)) {
+ mask = *s++;
+ if (isdigit(*s)) {
+ mask = 10 * (mask - '0') + (*s++ - '0');
+ if (mask >= 32) {
+ break;
+ }
+ } else {
+ mask -= '0';
+ }
+ switch (*args) {
+
+ case 'b':
+ opcode |= mask << 14;
+ continue;
+
+ case 'c':
+ opcode |= mask;
+ continue;
+
+ case 'D':
+ opcode |= mask << 25;
+ continue;
+ }
+ }
+ break;
+
+ case 'r': /* next operand must be a register */
+ case '1':
+ case '2':
+ case 'd':
+ if (*s++ == '%') {
+ switch (c = *s++) {
+
+ case 'f': /* frame pointer */
+ if (*s++ == 'p') {
+ mask = 0x1e;
+ break;
+ }
+ goto error;
+
+ case 'g': /* global register */
+ if (isoctal(c = *s++)) {
+ mask = c - '0';
+ break;
+ }
+ goto error;
+
+ case 'i': /* in register */
+ if (isoctal(c = *s++)) {
+ mask = c - '0' + 24;
+ break;
+ }
+ goto error;
+
+ case 'l': /* local register */
+ if (isoctal(c = *s++)) {
+ mask= (c - '0' + 16) ;
+ break;
+ }
+ goto error;
+
+ case 'o': /* out register */
+ if (isoctal(c = *s++)) {
+ mask= (c - '0' + 8) ;
+ break;
+ }
+ goto error;
+
+ case 's': /* stack pointer */
+ if (*s++ == 'p') {
+ mask= 0xe;
+ break;
+ }
+ goto error;
+
+ case 'r': /* any register */
+ if (!isdigit(c = *s++)) {
+ goto error;
+ }
+ /* FALLTHROUGH */
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (isdigit(*s)) {
+ if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) {
+ goto error;
+ }
+ } else {
+ c -= '0';
+ }
+ mask= c;
+ break;
+
+ default:
+ goto error;
+ }
+ /*
+ * Got the register, now figure out where
+ * it goes in the opcode.
+ */
+ switch (*args) {
+
+ case '1':
+ opcode |= mask << 14;
+ continue;
+
+ case '2':
+ opcode |= mask;
+ continue;
+
+ case 'd':
+ opcode |= mask << 25;
+ continue;
+
+ case 'r':
+ opcode |= (mask << 25) | (mask << 14);
+ continue;
+ }
+ }
+ break;
+
+ case 'e': /* next operand is a floating point register */
+ case 'f':
+ case 'g':
+ if (*s++ == '%' && *s++ == 'f' && isdigit(*s)) {
+ mask = *s++;
+ if (isdigit(*s)) {
+ mask = 10 * (mask - '0') + (*s++ - '0');
+ if (mask >= 32) {
+ break;
+ }
+ } else {
+ mask -= '0';
+ }
+ switch (*args) {
+
+ case 'e':
+ opcode |= mask << 14;
+ continue;
+
+ case 'f':
+ opcode |= mask;
+ continue;
+
+ case 'g':
+ opcode |= mask << 25;
+ continue;
+ }
+ }
+ break;
+
+ case 'F':
+ if (strncmp(s, "%fsr", 4) == 0) {
+ s += 4;
+ continue;
+ }
+ break;
+
+ case 'h': /* high 22 bits */
+ the_insn.reloc = RELOC_HI22;
+ goto immediate;
+
+ case 'l': /* 22 bit PC relative immediate */
+ the_insn.reloc = RELOC_WDISP22;
+ the_insn.pcrel = 1;
+ goto immediate;
+
+ case 'L': /* 30 bit immediate */
+ the_insn.reloc = RELOC_WDISP30;
+ the_insn.pcrel = 1;
+ goto immediate;
+
+ case 'i': /* 13 bit immediate */
+ the_insn.reloc = RELOC_BASE13;
+
+ /*FALLTHROUGH*/
+
+ immediate:
+ if(*s==' ')
+ s++;
+ if (*s == '%') {
+ if ((c = s[1]) == 'h' && s[2] == 'i') {
+ the_insn.reloc = RELOC_HI22;
+ s+=3;
+ } else if (c == 'l' && s[2] == 'o') {
+ the_insn.reloc = RELOC_LO10;
+ s+=3;
+ } else
+ break;
+ }
+ /* Note that if the getExpression() fails, we will still have
+ created U entries in the symbol table for the 'symbols'
+ in the input string. Try not to create U symbols for
+ registers, etc. */
+ {
+ /* This stuff checks to see if the expression ends
+ in +%reg If it does, it removes the register from
+ the expression, and re-sets 's' to point to the
+ right place */
+
+ char *s1;
+
+ for(s1=s;*s1 && *s1!=','&& *s1!=']';s1++)
+ ;
+
+ if(s1!=s && isdigit(s1[-1])) {
+ if(s1[-2]=='%' && s1[-3]=='+') {
+ s1-=3;
+ *s1='\0';
+ (void)getExpression(s);
+ *s1='+';
+ s=s1;
+ continue;
+ } else if(index("goli0123456789",s1[-2]) && s1[-3]=='%' && s1[-4]=='+') {
+ s1-=4;
+ *s1='\0';
+ (void)getExpression(s);
+ *s1='+';
+ s=s1;
+ continue;
+ }
+ }
+ }
+ (void)getExpression(s);
+ s = expr_end;
+ continue;
+
+ case 'a':
+ if (*s++ == 'a') {
+ opcode |= ANNUL;
+ continue;
+ }
+ break;
+
+ case 'A': /* alternate space */
+ if (isdigit(*s)) {
+ long num;
+
+ num=0;
+ while (isdigit(*s)) {
+ num= num*10 + *s-'0';
+ ++s;
+ }
+ opcode |= num<<5;
+ continue;
+ }
+ break;
+ /* abort(); */
+
+ case 'p':
+ if (strncmp(s, "%psr", 4) == 0) {
+ s += 4;
+ continue;
+ }
+ break;
+
+ case 'q': /* floating point queue */
+ if (strncmp(s, "%fq", 3) == 0) {
+ s += 3;
+ continue;
+ }
+ break;
+
+ case 'Q': /* coprocessor queue */
+ if (strncmp(s, "%cq", 3) == 0) {
+ s += 3;
+ continue;
+ }
+ break;
+
+ case 'S':
+ if (strcmp(str, "set") == 0) {
+ special_case = SPECIAL_CASE_SET;
+ continue;
+ }
+ break;
+
+ case 't':
+ if (strncmp(s, "%tbr", 4) != 0)
+ break;
+ s += 4;
+ continue;
+
+ case 'w':
+ if (strncmp(s, "%wim", 4) != 0)
+ break;
+ s += 4;
+ continue;
+
+ case 'y':
+ if (strncmp(s, "%y", 2) != 0)
+ break;
+ s += 2;
+ continue;
+
+ default:
+ abort();
+ }
+ break;
+ }
+ error:
+ if (match == FALSE)
+ {
+ /* Args don't match. */
+ if (&insn[1] - sparc_opcodes < NUMOPCODES
+ && !strcmp(insn->name, insn[1].name))
+ {
+ ++insn;
+ s = argsStart;
+ continue;
+ }
+ else
+ {
+ as_warn("Illegal operands");
+ return;
+ }
+ }
+ break;
+ }
+
+ the_insn.opcode = opcode;
+ return;
+}
+
+static int
+getExpression(str)
+ char *str;
+{
+ char *save_in;
+ segT seg;
+
+ save_in = input_line_pointer;
+ input_line_pointer = str;
+ switch (seg = expression(&the_insn.exp)) {
+
+ case SEG_ABSOLUTE:
+ case SEG_TEXT:
+ case SEG_DATA:
+ case SEG_BSS:
+ case SEG_UNKNOWN:
+ case SEG_DIFFERENCE:
+ case SEG_BIG:
+ case SEG_NONE:
+ break;
+
+ default:
+ the_insn.error = "bad segment";
+ expr_end = input_line_pointer;
+ input_line_pointer=save_in;
+ return 1;
+ }
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+ return 0;
+}
+
+
+/*
+ This is identical to the md_atof in m68k.c. I think this is right,
+ but I'm not sure.
+
+ Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof(type,litP,sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+ char *atof_ieee();
+
+ switch(type) {
+
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP=0;
+ return "Bad call to MD_ATOF()";
+ }
+ t=atof_ieee(input_line_pointer,type,words);
+ if(t)
+ input_line_pointer=t;
+ *sizeP=prec * sizeof(LITTLENUM_TYPE);
+ for(wordP=words;prec--;) {
+ md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
+ litP+=sizeof(LITTLENUM_TYPE);
+ }
+ return ""; /* Someone should teach Dean about null pointers */
+}
+
+/*
+ * Write out big-endian.
+ */
+void
+md_number_to_chars(buf,val,n)
+ char *buf;
+ long val;
+ int n;
+{
+
+ switch(n) {
+
+ case 4:
+ *buf++ = val >> 24;
+ *buf++ = val >> 16;
+ case 2:
+ *buf++ = val >> 8;
+ case 1:
+ *buf = val;
+ break;
+
+ default:
+ abort();
+ }
+ return;
+}
+
+void
+md_number_to_imm(buf,val,n, fixP, seg_type)
+ char *buf;
+ long val;
+ int n;
+ fixS *fixP;
+ int seg_type;
+{
+ /* if (seg_type != N_TEXT || fixP->fx_r_type == NO_RELOC) { */
+ if ( (seg_type != N_TEXT && fixP->fx_r_type > RELOC_DISP32 )
+ || fixP->fx_r_type == NO_RELOC) {
+ /* should never get here for current relocs ... */
+
+ switch (n) {
+ case 1:
+ *buf = val;
+ break;
+ case 2:
+ *buf++ = (val>>8);
+ *buf = val;
+ break;
+ case 4:
+ *buf++ = (val>>24);
+ *buf++ = (val>>16);
+ *buf++ = (val>>8);
+ *buf = val;
+ break;
+ default:
+ abort();
+ }
+ return;
+ }
+
+ assert(n == 4);
+ assert(fixP->fx_r_type < NO_RELOC);
+
+ /*
+ * This is a hack. There should be a better way to
+ * handle this.
+ */
+ if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) {
+ val += fixP->fx_where + fixP->fx_frag->fr_address;
+ }
+
+ switch (fixP->fx_r_type) {
+
+ case RELOC_32:
+ buf[0] = 0; /* val >> 24; */
+ buf[1] = 0; /* val >> 16; */
+ buf[2] = 0; /* val >> 8; */
+ buf[3] = 0; /* val; */
+ break;
+
+#if 0
+ case RELOC_8: /* These don't seem to ever be needed. */
+ case RELOC_16:
+ case RELOC_DISP8:
+ case RELOC_DISP16:
+ case RELOC_DISP32:
+#endif
+ case RELOC_WDISP30:
+ val = (val >>= 2) + 1;
+ buf[0] |= (val >> 24) & 0x3f;
+ buf[1]= (val >> 16);
+ buf[2] = val >> 8;
+ buf[3] = val;
+ break;
+
+ case RELOC_HI22:
+ if(!fixP->fx_addsy) {
+ buf[1] |= (val >> 26) & 0x3f;
+ buf[2] = val >> 18;
+ buf[3] = val >> 10;
+ } else {
+ buf[2]=0;
+ buf[3]=0;
+ }
+ break;
+#if 0
+ case RELOC_22:
+ case RELOC_13:
+#endif
+ case RELOC_LO10:
+ if(!fixP->fx_addsy) {
+ buf[2] |= (val >> 8) & 0x03;
+ buf[3] = val;
+ } else
+ buf[3]=0;
+ break;
+#if 0
+ case RELOC_SFA_BASE:
+ case RELOC_SFA_OFF13:
+ case RELOC_BASE10:
+#endif
+ case RELOC_BASE13:
+ buf[2] |= (val >> 8) & 0x1f;
+ buf[3] = val;
+ break;
+
+ case RELOC_WDISP22:
+ val = (val >>= 2) + 1;
+ /* FALLTHROUGH */
+ case RELOC_BASE22:
+ buf[1] |= (val >> 16) & 0x3f;
+ buf[2] = val >> 8;
+ buf[3] = val;
+ break;
+
+#if 0
+ case RELOC_PC10:
+ case RELOC_PC22:
+ case RELOC_JMP_TBL:
+ case RELOC_SEGOFF16:
+ case RELOC_GLOB_DAT:
+ case RELOC_JMP_SLOT:
+ case RELOC_RELATIVE:
+#endif
+
+ case NO_RELOC:
+ default:
+ as_warn("bad relocation type: 0x%02x", fixP->fx_r_type);
+ break;
+ }
+ return;
+}
+
+/* should never be called for sparc */
+void
+md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ long from_addr, to_addr;
+{
+ fprintf(stderr, "sparc_create_short_jmp\n");
+ abort();
+}
+
+/* should never be called for sparc */
+void
+md_number_to_disp(buf,val,n)
+ char *buf;
+ long val;
+{
+ fprintf(stderr, "md_number_to_disp\n");
+ abort();
+}
+
+/* should never be called for sparc */
+void
+md_number_to_field(buf,val,fix)
+ char *buf;
+ long val;
+ void *fix;
+{
+ fprintf(stderr, "sparc_number_to_field\n");
+ abort();
+}
+
+/* the bit-field entries in the relocation_info struct plays hell
+ with the byte-order problems of cross-assembly. So as a hack,
+ I added this mach. dependent ri twiddler. Ugly, but it gets
+ you there. -KWK */
+/* on sparc: first 4 bytes are normal unsigned long address, next three
+ bytes are index, most sig. byte first. Byte 7 is broken up with
+ bit 7 as external, bits 6 & 5 unused, and the lower
+ five bits as relocation type. Next 4 bytes are long int addend. */
+/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
+void
+md_ri_to_chars(ri_p, ri)
+ struct reloc_info_sparc *ri_p, ri;
+{
+ unsigned char the_bytes[sizeof(*ri_p)];
+
+ /* this is easy */
+ md_number_to_chars(the_bytes, ri.r_address, sizeof(ri.r_address));
+ /* now the fun stuff */
+ the_bytes[4] = (ri.r_index >> 16) & 0x0ff;
+ the_bytes[5] = (ri.r_index >> 8) & 0x0ff;
+ the_bytes[6] = ri.r_index & 0x0ff;
+ the_bytes[7] = ((ri.r_extern << 7) & 0x80) | (0 & 0x60) | (ri.r_type & 0x1F);
+ /* Also easy */
+ md_number_to_chars(&the_bytes[8], ri.r_addend, sizeof(ri.r_addend));
+ /* now put it back where you found it, Junior... */
+ bcopy (the_bytes, (char *)ri_p, sizeof(*ri_p));
+}
+
+/* should never be called for sparc */
+void
+md_convert_frag(fragP)
+ register fragS *fragP;
+{
+ fprintf(stderr, "sparc_convert_frag\n");
+ abort();
+}
+
+/* should never be called for sparc */
+void
+md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ long from_addr,
+ to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ fprintf(stderr, "sparc_create_long_jump\n");
+ abort();
+}
+
+/* should never be called for sparc */
+int
+md_estimate_size_before_relax(fragP, segtype)
+ register fragS *fragP;
+{
+ fprintf(stderr, "sparc_estimate_size_before_relax\n");
+ abort();
+ return 0;
+}
+
+#if 0
+/* for debugging only */
+static void
+print_insn(insn)
+ struct sparc_it *insn;
+{
+ char *Reloc[] = {
+ "RELOC_8",
+ "RELOC_16",
+ "RELOC_32",
+ "RELOC_DISP8",
+ "RELOC_DISP16",
+ "RELOC_DISP32",
+ "RELOC_WDISP30",
+ "RELOC_WDISP22",
+ "RELOC_HI22",
+ "RELOC_22",
+ "RELOC_13",
+ "RELOC_LO10",
+ "RELOC_SFA_BASE",
+ "RELOC_SFA_OFF13",
+ "RELOC_BASE10",
+ "RELOC_BASE13",
+ "RELOC_BASE22",
+ "RELOC_PC10",
+ "RELOC_PC22",
+ "RELOC_JMP_TBL",
+ "RELOC_SEGOFF16",
+ "RELOC_GLOB_DAT",
+ "RELOC_JMP_SLOT",
+ "RELOC_RELATIVE",
+ "NO_RELOC"
+ };
+
+ if (insn->error) {
+ fprintf(stderr, "ERROR: %s\n");
+ }
+ fprintf(stderr, "opcode=0x%08x\n", insn->opcode);
+ fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]);
+ fprintf(stderr, "exp = {\n");
+ fprintf(stderr, "\t\tX_add_symbol = %s\n",
+ insn->exp.X_add_symbol ?
+ (insn->exp.X_add_symbol->sy_name ?
+ insn->exp.X_add_symbol->sy_name : "???") : "0");
+ fprintf(stderr, "\t\tX_sub_symbol = %s\n",
+ insn->exp.X_subtract_symbol ?
+ (insn->exp.X_subtract_symbol->sy_name ?
+ insn->exp.X_subtract_symbol->sy_name : "???") : "0");
+ fprintf(stderr, "\t\tX_add_number = %d\n",
+ insn->exp.X_add_number);
+ fprintf(stderr, "}\n");
+ return;
+}
+#endif
+
+/*
+ * Sparc relocations are completely different, so it needs
+ * this machine dependent routine to emit them.
+ */
+void
+emit_relocations(fixP, segment_address_in_file)
+ register fixS *fixP;
+ relax_addressT segment_address_in_file;
+{
+ struct reloc_info_sparc ri;
+ register symbolS *symbolP;
+ extern char *next_object_file_charP;
+ long add_number;
+
+ bzero((char *) &ri, sizeof(ri));
+ for (; fixP; fixP = fixP->fx_next) {
+
+ if (fixP->fx_r_type >= NO_RELOC) {
+ fprintf(stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type);
+ abort();
+ }
+
+ if ((symbolP = fixP->fx_addsy) != NULL) {
+ ri.r_address = fixP->fx_frag->fr_address +
+ fixP->fx_where - segment_address_in_file;
+ if ((symbolP->sy_type & N_TYPE) == N_UNDF) {
+ ri.r_extern = 1;
+ ri.r_index = symbolP->sy_number;
+ } else {
+ ri.r_extern = 0;
+ ri.r_index = symbolP->sy_type & N_TYPE;
+ }
+ if (symbolP && symbolP->sy_frag) {
+ ri.r_addend = symbolP->sy_frag->fr_address;
+ }
+ ri.r_type = fixP->fx_r_type;
+ if (fixP->fx_pcrel) {
+/* ri.r_addend -= fixP->fx_where; */
+ ri.r_addend -= ri.r_address;
+ } else {
+ ri.r_addend = fixP->fx_addnumber;
+ }
+
+/* md_ri_to_chars((char *) &ri, ri); */
+ append(&next_object_file_charP, (char *)& ri, sizeof(ri));
+ }
+ }
+ return;
+}
+
+int
+md_parse_option(argP,cntP,vecP)
+ char **argP;
+ int *cntP;
+ char ***vecP;
+{
+ return 1;
+}
+
diff --git a/gnu/usr.bin/gas/config/sparc.h b/gnu/usr.bin/gas/config/sparc.h
new file mode 100644
index 00000000000..ac89437b386
--- /dev/null
+++ b/gnu/usr.bin/gas/config/sparc.h
@@ -0,0 +1,52 @@
+/* sparc.h -- Header file for the SPARC
+ Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/*
+ * The following enum and struct were borrowed from
+ * sunOS /usr/include/sun4/a.out.h
+ *
+ */
+
+enum reloc_type
+{
+ RELOC_8, RELOC_16, RELOC_32, RELOC_DISP8,
+ RELOC_DISP16, RELOC_DISP32, RELOC_WDISP30, RELOC_WDISP22,
+ RELOC_HI22, RELOC_22, RELOC_13, RELOC_LO10,
+ RELOC_SFA_BASE, RELOC_SFA_OFF13, RELOC_BASE10, RELOC_BASE13,
+ RELOC_BASE22, RELOC_PC10, RELOC_PC22, RELOC_JMP_TBL,
+ RELOC_SEGOFF16, RELOC_GLOB_DAT, RELOC_JMP_SLOT, RELOC_RELATIVE,
+
+ NO_RELOC
+};
+
+struct reloc_info_sparc
+{
+ unsigned long int r_address;
+/*
+ * Using bit fields here is a bad idea because the order is not portable. :-(
+ */
+ unsigned int r_index : 24;
+ unsigned int r_extern : 1;
+ unsigned int unused : 2;
+ enum reloc_type r_type : 5;
+ long int r_addend;
+};
+
+#define relocation_info reloc_info_sparc
+
diff --git a/gnu/usr.bin/gas/config/vax-inst.h b/gnu/usr.bin/gas/config/vax-inst.h
new file mode 100644
index 00000000000..4a8947054fd
--- /dev/null
+++ b/gnu/usr.bin/gas/config/vax-inst.h
@@ -0,0 +1,77 @@
+/* vax-inst.h - GNU - Part of vax.c
+ Copyright (C) 1987 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/*
+ * This is part of vax-ins-parse.c & friends.
+ * We want to parse a vax instruction text into a tree defined here.
+ */
+
+#define VIT_MAX_OPERANDS (6) /* maximum number of operands in one */
+ /* single vax instruction */
+
+struct vop /* vax instruction operand */
+{
+ short int vop_ndx; /* -1, or index register. eg 7=[R7] */
+ short int vop_reg; /* -1, or register number. eg @I^#=0xF */
+ /* Helps distinguish "abs" from "abs(PC)". */
+ short int vop_mode; /* addressing mode 4 bits. eg I^#=0x9 */
+ char vop_short; /* operand displacement length as written */
+ /* ' '=none, "bilsw"=B^I^L^S^W^. */
+ char vop_access; /* 'b'branch ' 'no-instruction 'amrvw'norm */
+ char vop_width; /* Operand width, one of "bdfghloqw" */
+ char * vop_warn; /* warning message of this operand, if any */
+ char * vop_error; /* say if operand is inappropriate */
+ char * vop_expr_begin; /* Unparsed expression, 1st char ... */
+ char * vop_expr_end; /* ... last char. */
+ unsigned char vop_nbytes; /* number of bytes in datum */
+};
+
+
+typedef long int vax_opcodeT; /* For initialising array of opcodes */
+ /* Some synthetic opcodes > 16 bits! */
+
+#define VIT_OPCODE_SYNTHETIC 0x80000000 /* Not real hardware instruction. */
+#define VIT_OPCODE_SPECIAL 0x40000000 /* Not normal branch optimising. */
+ /* Never set without ..._SYNTHETIC */
+
+#define VAX_WIDTH_UNCONDITIONAL_JUMP '-' /* These are encoded into */
+#define VAX_WIDTH_CONDITIONAL_JUMP '?' /* vop_width when vop_access=='b' */
+#define VAX_WIDTH_WORD_JUMP '!' /* and VIT_OPCODE_SYNTHETIC set. */
+#define VAX_WIDTH_BYTE_JUMP ':' /* */
+
+#define VAX_JMP (0x17) /* Useful for branch optimising. Jump instr*/
+#define VAX_PC_RELATIVE_MODE (0xef) /* Use it after VAX_JMP */
+#define VAX_ABSOLUTE_MODE (0x9F) /* Use as @#... */
+#define VAX_BRB (0x11) /* Canonical branch. */
+#define VAX_BRW (0x31) /* Another canonical branch */
+#define VAX_WIDEN_WORD (0x20) /* Add this to byte branch to get word br. */
+#define VAX_WIDEN_LONG (0x6) /* Add this to byte branch to get long jmp.*/
+ /* Needs VAX_PC_RELATIVE_MODE byte after it*/
+
+struct vit /* vax instruction tree */
+{
+ /* vit_opcode is char[] for portability. */
+ char vit_opcode [ sizeof (vax_opcodeT) ];
+ unsigned char vit_opcode_nbytes; /* How long is _opcode? (chars) */
+ unsigned char vit_operands;/* */
+ struct vop vit_operand[VIT_MAX_OPERANDS]; /* operands */
+ char * vit_error; /* "" or error text */
+};
+
+/* end: vax-inst.h */
diff --git a/gnu/usr.bin/gas/config/vax-opcode.h b/gnu/usr.bin/gas/config/vax-opcode.h
new file mode 100644
index 00000000000..d604e3f9c65
--- /dev/null
+++ b/gnu/usr.bin/gas/config/vax-opcode.h
@@ -0,0 +1,382 @@
+/* Vax opcde list.
+ Copyright (C) 1989, Free Software Foundation, Inc.
+
+This file is part of GDB and GAS.
+
+GDB and GAS are free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB and GAS are distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB or GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef vax_opcodeT
+#define vax_opcodeT int
+#endif /* no vax_opcodeT */
+
+struct vot_wot /* vax opcode table: wot to do with this */
+ /* particular opcode */
+{
+ char * args; /* how to compile said opcode */
+ vax_opcodeT code; /* op-code (may be > 8 bits!) */
+};
+
+struct vot /* vax opcode text */
+{
+ char * name; /* opcode name: lowercase string [key] */
+ struct vot_wot detail; /* rest of opcode table [datum] */
+};
+
+#define vot_how args
+#define vot_code code
+#define vot_detail detail
+#define vot_name name
+
+static const struct vot
+votstrs[] =
+{
+{ "halt", {"", 0x00 } },
+{ "nop", {"", 0x01 } },
+{ "rei", {"", 0x02 } },
+{ "bpt", {"", 0x03 } },
+{ "ret", {"", 0x04 } },
+{ "rsb", {"", 0x05 } },
+{ "ldpctx", {"", 0x06 } },
+{ "svpctx", {"", 0x07 } },
+{ "cvtps", {"rwabrwab", 0x08 } },
+{ "cvtsp", {"rwabrwab", 0x09 } },
+{ "index", {"rlrlrlrlrlwl", 0x0a } },
+{ "crc", {"abrlrwab", 0x0b } },
+{ "prober", {"rbrwab", 0x0c } },
+{ "probew", {"rbrwab", 0x0d } },
+{ "insque", {"abab", 0x0e } },
+{ "remque", {"abwl", 0x0f } },
+{ "bsbb", {"bb", 0x10 } },
+{ "brb", {"bb", 0x11 } },
+{ "bneq", {"bb", 0x12 } },
+{ "bnequ", {"bb", 0x12 } },
+{ "beql", {"bb", 0x13 } },
+{ "beqlu", {"bb", 0x13 } },
+{ "bgtr", {"bb", 0x14 } },
+{ "bleq", {"bb", 0x15 } },
+{ "jsb", {"ab", 0x16 } },
+{ "jmp", {"ab", 0x17 } },
+{ "bgeq", {"bb", 0x18 } },
+{ "blss", {"bb", 0x19 } },
+{ "bgtru", {"bb", 0x1a } },
+{ "blequ", {"bb", 0x1b } },
+{ "bvc", {"bb", 0x1c } },
+{ "bvs", {"bb", 0x1d } },
+{ "bcc", {"bb", 0x1e } },
+{ "bgequ", {"bb", 0x1e } },
+{ "blssu", {"bb", 0x1f } },
+{ "bcs", {"bb", 0x1f } },
+{ "addp4", {"rwabrwab", 0x20 } },
+{ "addp6", {"rwabrwabrwab", 0x21 } },
+{ "subp4", {"rwabrwab", 0x22 } },
+{ "subp6", {"rwabrwabrwab", 0x23 } },
+{ "cvtpt", {"rwababrwab", 0x24 } },
+{ "mulp", {"rwabrwabrwab", 0x25 } },
+{ "cvttp", {"rwababrwab", 0x26 } },
+{ "divp", {"rwabrwabrwab", 0x27 } },
+{ "movc3", {"rwabab", 0x28 } },
+{ "cmpc3", {"rwabab", 0x29 } },
+{ "scanc", {"rwababrb", 0x2a } },
+{ "spanc", {"rwababrb", 0x2b } },
+{ "movc5", {"rwabrbrwab", 0x2c } },
+{ "cmpc5", {"rwabrbrwab", 0x2d } },
+{ "movtc", {"rwabrbabrwab", 0x2e } },
+{ "movtuc", {"rwabrbabrwab", 0x2f } },
+{ "bsbw", {"bw", 0x30 } },
+{ "brw", {"bw", 0x31 } },
+{ "cvtwl", {"rwwl", 0x32 } },
+{ "cvtwb", {"rwwb", 0x33 } },
+{ "movp", {"rwabab", 0x34 } },
+{ "cmpp3", {"rwabab", 0x35 } },
+{ "cvtpl", {"rwabwl", 0x36 } },
+{ "cmpp4", {"rwabrwab", 0x37 } },
+{ "editpc", {"rwababab", 0x38 } },
+{ "matchc", {"rwabrwab", 0x39 } },
+{ "locc", {"rbrwab", 0x3a } },
+{ "skpc", {"rbrwab", 0x3b } },
+{ "movzwl", {"rwwl", 0x3c } },
+{ "acbw", {"rwrwmwbw", 0x3d } },
+{ "movaw", {"awwl", 0x3e } },
+{ "pushaw", {"aw", 0x3f } },
+{ "addf2", {"rfmf", 0x40 } },
+{ "addf3", {"rfrfwf", 0x41 } },
+{ "subf2", {"rfmf", 0x42 } },
+{ "subf3", {"rfrfwf", 0x43 } },
+{ "mulf2", {"rfmf", 0x44 } },
+{ "mulf3", {"rfrfwf", 0x45 } },
+{ "divf2", {"rfmf", 0x46 } },
+{ "divf3", {"rfrfwf", 0x47 } },
+{ "cvtfb", {"rfwb", 0x48 } },
+{ "cvtfw", {"rfww", 0x49 } },
+{ "cvtfl", {"rfwl", 0x4a } },
+{ "cvtrfl", {"rfwl", 0x4b } },
+{ "cvtbf", {"rbwf", 0x4c } },
+{ "cvtwf", {"rwwf", 0x4d } },
+{ "cvtlf", {"rlwf", 0x4e } },
+{ "acbf", {"rfrfmfbw", 0x4f } },
+{ "movf", {"rfwf", 0x50 } },
+{ "cmpf", {"rfrf", 0x51 } },
+{ "mnegf", {"rfwf", 0x52 } },
+{ "tstf", {"rf", 0x53 } },
+{ "emodf", {"rfrbrfwlwf", 0x54 } },
+{ "polyf", {"rfrwab", 0x55 } },
+{ "cvtfd", {"rfwd", 0x56 } },
+ /* opcode 57 is not defined yet */
+{ "adawi", {"rwmw", 0x58 } },
+ /* opcode 59 is not defined yet */
+ /* opcode 5a is not defined yet */
+ /* opcode 5b is not defined yet */
+{ "insqhi", {"abaq", 0x5c } },
+{ "insqti", {"abaq", 0x5d } },
+{ "remqhi", {"aqwl", 0x5e } },
+{ "remqti", {"aqwl", 0x5f } },
+{ "addd2", {"rdmd", 0x60 } },
+{ "addd3", {"rdrdwd", 0x61 } },
+{ "subd2", {"rdmd", 0x62 } },
+{ "subd3", {"rdrdwd", 0x63 } },
+{ "muld2", {"rdmd", 0x64 } },
+{ "muld3", {"rdrdwd", 0x65 } },
+{ "divd2", {"rdmd", 0x66 } },
+{ "divd3", {"rdrdwd", 0x67 } },
+{ "cvtdb", {"rdwb", 0x68 } },
+{ "cvtdw", {"rdww", 0x69 } },
+{ "cvtdl", {"rdwl", 0x6a } },
+{ "cvtrdl", {"rdwl", 0x6b } },
+{ "cvtbd", {"rbwd", 0x6c } },
+{ "cvtwd", {"rwwd", 0x6d } },
+{ "cvtld", {"rlwd", 0x6e } },
+{ "acbd", {"rdrdmdbw", 0x6f } },
+{ "movd", {"rdwd", 0x70 } },
+{ "cmpd", {"rdrd", 0x71 } },
+{ "mnegd", {"rdwd", 0x72 } },
+{ "tstd", {"rd", 0x73 } },
+{ "emodd", {"rdrbrdwlwd", 0x74 } },
+{ "polyd", {"rdrwab", 0x75 } },
+{ "cvtdf", {"rdwf", 0x76 } },
+ /* opcode 77 is not defined yet */
+{ "ashl", {"rbrlwl", 0x78 } },
+{ "ashq", {"rbrqwq", 0x79 } },
+{ "emul", {"rlrlrlwq", 0x7a } },
+{ "ediv", {"rlrqwlwl", 0x7b } },
+{ "clrd", {"wd", 0x7c } },
+{ "clrg", {"wg", 0x7c } },
+{ "clrq", {"wd", 0x7c } },
+{ "movq", {"rqwq", 0x7d } },
+{ "movaq", {"aqwl", 0x7e } },
+{ "movad", {"adwl", 0x7e } },
+{ "pushaq", {"aq", 0x7f } },
+{ "pushad", {"ad", 0x7f } },
+{ "addb2", {"rbmb", 0x80 } },
+{ "addb3", {"rbrbwb", 0x81 } },
+{ "subb2", {"rbmb", 0x82 } },
+{ "subb3", {"rbrbwb", 0x83 } },
+{ "mulb2", {"rbmb", 0x84 } },
+{ "mulb3", {"rbrbwb", 0x85 } },
+{ "divb2", {"rbmb", 0x86 } },
+{ "divb3", {"rbrbwb", 0x87 } },
+{ "bisb2", {"rbmb", 0x88 } },
+{ "bisb3", {"rbrbwb", 0x89 } },
+{ "bicb2", {"rbmb", 0x8a } },
+{ "bicb3", {"rbrbwb", 0x8b } },
+{ "xorb2", {"rbmb", 0x8c } },
+{ "xorb3", {"rbrbwb", 0x8d } },
+{ "mnegb", {"rbwb", 0x8e } },
+{ "caseb", {"rbrbrb", 0x8f } },
+{ "movb", {"rbwb", 0x90 } },
+{ "cmpb", {"rbrb", 0x91 } },
+{ "mcomb", {"rbwb", 0x92 } },
+{ "bitb", {"rbrb", 0x93 } },
+{ "clrb", {"wb", 0x94 } },
+{ "tstb", {"rb", 0x95 } },
+{ "incb", {"mb", 0x96 } },
+{ "decb", {"mb", 0x97 } },
+{ "cvtbl", {"rbwl", 0x98 } },
+{ "cvtbw", {"rbww", 0x99 } },
+{ "movzbl", {"rbwl", 0x9a } },
+{ "movzbw", {"rbww", 0x9b } },
+{ "rotl", {"rbrlwl", 0x9c } },
+{ "acbb", {"rbrbmbbw", 0x9d } },
+{ "movab", {"abwl", 0x9e } },
+{ "pushab", {"ab", 0x9f } },
+{ "addw2", {"rwmw", 0xa0 } },
+{ "addw3", {"rwrwww", 0xa1 } },
+{ "subw2", {"rwmw", 0xa2 } },
+{ "subw3", {"rwrwww", 0xa3 } },
+{ "mulw2", {"rwmw", 0xa4 } },
+{ "mulw3", {"rwrwww", 0xa5 } },
+{ "divw2", {"rwmw", 0xa6 } },
+{ "divw3", {"rwrwww", 0xa7 } },
+{ "bisw2", {"rwmw", 0xa8 } },
+{ "bisw3", {"rwrwww", 0xa9 } },
+{ "bicw2", {"rwmw", 0xaa } },
+{ "bicw3", {"rwrwww", 0xab } },
+{ "xorw2", {"rwmw", 0xac } },
+{ "xorw3", {"rwrwww", 0xad } },
+{ "mnegw", {"rwww", 0xae } },
+{ "casew", {"rwrwrw", 0xaf } },
+{ "movw", {"rwww", 0xb0 } },
+{ "cmpw", {"rwrw", 0xb1 } },
+{ "mcomw", {"rwww", 0xb2 } },
+{ "bitw", {"rwrw", 0xb3 } },
+{ "clrw", {"ww", 0xb4 } },
+{ "tstw", {"rw", 0xb5 } },
+{ "incw", {"mw", 0xb6 } },
+{ "decw", {"mw", 0xb7 } },
+{ "bispsw", {"rw", 0xb8 } },
+{ "bicpsw", {"rw", 0xb9 } },
+{ "popr", {"rw", 0xba } },
+{ "pushr", {"rw", 0xbb } },
+{ "chmk", {"rw", 0xbc } },
+{ "chme", {"rw", 0xbd } },
+{ "chms", {"rw", 0xbe } },
+{ "chmu", {"rw", 0xbf } },
+{ "addl2", {"rlml", 0xc0 } },
+{ "addl3", {"rlrlwl", 0xc1 } },
+{ "subl2", {"rlml", 0xc2 } },
+{ "subl3", {"rlrlwl", 0xc3 } },
+{ "mull2", {"rlml", 0xc4 } },
+{ "mull3", {"rlrlwl", 0xc5 } },
+{ "divl2", {"rlml", 0xc6 } },
+{ "divl3", {"rlrlwl", 0xc7 } },
+{ "bisl2", {"rlml", 0xc8 } },
+{ "bisl3", {"rlrlwl", 0xc9 } },
+{ "bicl2", {"rlml", 0xca } },
+{ "bicl3", {"rlrlwl", 0xcb } },
+{ "xorl2", {"rlml", 0xcc } },
+{ "xorl3", {"rlrlwl", 0xcd } },
+{ "mnegl", {"rlwl", 0xce } },
+{ "casel", {"rlrlrl", 0xcf } },
+{ "movl", {"rlwl", 0xd0 } },
+{ "cmpl", {"rlrl", 0xd1 } },
+{ "mcoml", {"rlwl", 0xd2 } },
+{ "bitl", {"rlrl", 0xd3 } },
+{ "clrf", {"wf", 0xd4 } },
+{ "clrl", {"wl", 0xd4 } },
+{ "tstl", {"rl", 0xd5 } },
+{ "incl", {"ml", 0xd6 } },
+{ "decl", {"ml", 0xd7 } },
+{ "adwc", {"rlml", 0xd8 } },
+{ "sbwc", {"rlml", 0xd9 } },
+{ "mtpr", {"rlrl", 0xda } },
+{ "mfpr", {"rlwl", 0xdb } },
+{ "movpsl", {"wl", 0xdc } },
+{ "pushl", {"rl", 0xdd } },
+{ "moval", {"alwl", 0xde } },
+{ "movaf", {"afwl", 0xde } },
+{ "pushal", {"al", 0xdf } },
+{ "pushaf", {"af", 0xdf } },
+{ "bbs", {"rlabbb", 0xe0 } },
+{ "bbc", {"rlabbb", 0xe1 } },
+{ "bbss", {"rlabbb", 0xe2 } },
+{ "bbcs", {"rlabbb", 0xe3 } },
+{ "bbsc", {"rlabbb", 0xe4 } },
+{ "bbcc", {"rlabbb", 0xe5 } },
+{ "bbssi", {"rlabbb", 0xe6 } },
+{ "bbcci", {"rlabbb", 0xe7 } },
+{ "blbs", {"rlbb", 0xe8 } },
+{ "blbc", {"rlbb", 0xe9 } },
+{ "ffs", {"rlrbvbwl", 0xea } },
+{ "ffc", {"rlrbvbwl", 0xeb } },
+{ "cmpv", {"rlrbvbrl", 0xec } },
+{ "cmpzv", {"rlrbvbrl", 0xed } },
+{ "extv", {"rlrbvbwl", 0xee } },
+{ "extzv", {"rlrbvbwl", 0xef } },
+{ "insv", {"rlrlrbvb", 0xf0 } },
+{ "acbl", {"rlrlmlbw", 0xf1 } },
+{ "aoblss", {"rlmlbb", 0xf2 } },
+{ "aobleq", {"rlmlbb", 0xf3 } },
+{ "sobgeq", {"mlbb", 0xf4 } },
+{ "sobgtr", {"mlbb", 0xf5 } },
+{ "cvtlb", {"rlwb", 0xf6 } },
+{ "cvtlw", {"rlww", 0xf7 } },
+{ "ashp", {"rbrwabrbrwab", 0xf8 } },
+{ "cvtlp", {"rlrwab", 0xf9 } },
+{ "callg", {"abab", 0xfa } },
+{ "calls", {"rlab", 0xfb } },
+{ "xfc", {"", 0xfc } },
+ /* undefined opcodes here */
+{ "cvtdh", {"rdwh", 0x32fd } },
+{ "cvtgf", {"rgwh", 0x33fd } },
+{ "addg2", {"rgmg", 0x40fd } },
+{ "addg3", {"rgrgwg", 0x41fd } },
+{ "subg2", {"rgmg", 0x42fd } },
+{ "subg3", {"rgrgwg", 0x43fd } },
+{ "mulg2", {"rgmg", 0x44fd } },
+{ "mulg3", {"rgrgwg", 0x45fd } },
+{ "divg2", {"rgmg", 0x46fd } },
+{ "divg3", {"rgrgwg", 0x47fd } },
+{ "cvtgb", {"rgwb", 0x48fd } },
+{ "cvtgw", {"rgww", 0x49fd } },
+{ "cvtgl", {"rgwl", 0x4afd } },
+{ "cvtrgl", {"rgwl", 0x4bfd } },
+{ "cvtbg", {"rbwg", 0x4cfd } },
+{ "cvtwg", {"rwwg", 0x4dfd } },
+{ "cvtlg", {"rlwg", 0x4efd } },
+{ "acbg", {"rgrgmgbw", 0x4ffd } },
+{ "movg", {"rgwg", 0x50fd } },
+{ "cmpg", {"rgrg", 0x51fd } },
+{ "mnegg", {"rgwg", 0x52fd } },
+{ "tstg", {"rg", 0x53fd } },
+{ "emodg", {"rgrwrgwlwg", 0x54fd } },
+{ "polyg", {"rgrwab", 0x55fd } },
+{ "cvtgh", {"rgwh", 0x56fd } },
+ /* undefined opcodes here */
+{ "addh2", {"rhmh", 0x60fd } },
+{ "addh3", {"rhrhwh", 0x61fd } },
+{ "subh2", {"rhmh", 0x62fd } },
+{ "subh3", {"rhrhwh", 0x63fd } },
+{ "mulh2", {"rhmh", 0x64fd } },
+{ "mulh3", {"rhrhwh", 0x65fd } },
+{ "divh2", {"rhmh", 0x66fd } },
+{ "divh3", {"rhrhwh", 0x67fd } },
+{ "cvthb", {"rhwb", 0x68fd } },
+{ "cvthw", {"rhww", 0x69fd } },
+{ "cvthl", {"rhwl", 0x6afd } },
+{ "cvtrhl", {"rhwl", 0x6bfd } },
+{ "cvtbh", {"rbwh", 0x6cfd } },
+{ "cvtwh", {"rwwh", 0x6dfd } },
+{ "cvtlh", {"rlwh", 0x6efd } },
+{ "acbh", {"rhrhmhbw", 0x6ffd } },
+{ "movh", {"rhwh", 0x70fd } },
+{ "cmph", {"rhrh", 0x71fd } },
+{ "mnegh", {"rhwh", 0x72fd } },
+{ "tsth", {"rh", 0x73fd } },
+{ "emodh", {"rhrwrhwlwh", 0x74fd } },
+{ "polyh", {"rhrwab", 0x75fd } },
+{ "cvthg", {"rhwg", 0x76fd } },
+ /* undefined opcodes here */
+{ "clrh", {"wh", 0x7cfd } },
+{ "clro", {"wo", 0x7cfd } },
+{ "movo", {"rowo", 0x7dfd } },
+{ "movah", {"ahwl", 0x7efd } },
+{ "movao", {"aowl", 0x7efd } },
+{ "pushah", {"ah", 0x7ffd } },
+{ "pushao", {"ao", 0x7ffd } },
+ /* undefined opcodes here */
+{ "cvtfh", {"rfwh", 0x98fd } },
+{ "cvtfg", {"rfwg", 0x99fd } },
+ /* undefined opcodes here */
+{ "cvthf", {"rhwf", 0xf6fd } },
+{ "cvthd", {"rhwd", 0xf7fd } },
+ /* undefined opcodes here */
+{ "bugl", {"rl", 0xfdff } },
+{ "bugw", {"rw", 0xfeff } },
+ /* undefined opcodes here */
+
+{ "" , "" } /* empty is end sentinel */
+
+}; /* votstrs */
+
+/* end: vax.opcode.h */
diff --git a/gnu/usr.bin/gas/config/vax.c b/gnu/usr.bin/gas/config/vax.c
new file mode 100644
index 00000000000..b8cd6ed1573
--- /dev/null
+++ b/gnu/usr.bin/gas/config/vax.c
@@ -0,0 +1,3364 @@
+/* vax.c - vax-specific -
+ Copyright (C) 1987 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+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 "read.h"
+#include "flonum.h"
+#include "vax-inst.h"
+#include "md.h"
+#include "obstack.h" /* For FRAG_APPEND_1_CHAR macro in "frags.h" */
+#include "frags.h"
+#include "struc-symbol.h"
+#include "expr.h"
+#include "symbols.h"
+
+/* This is the number to put at the beginning of the a.out file */
+long omagic = OMAGIC;
+
+/* These chars start a comment anywhere in a source file (except inside
+ another comment */
+const char comment_chars[] = "#";
+
+/* These chars only start a comment at the beginning of a line. */
+/* Note that for the VAX the are the same as comment_chars above. */
+const char line_comment_chars[] = "#";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* as in 0f123.456 */
+/* or 0H1.234E-12 (see exp chars above) */
+const char FLT_CHARS[] = "dDfFgGhH";
+
+/* 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.
+ */
+
+static expressionS /* Hold details of an operand expression */
+ exp_of_operand[VIT_MAX_OPERANDS];
+
+static struct vit
+ v; /* A vax instruction after decoding. */
+
+LITTLENUM_TYPE big_operand_bits[VIT_MAX_OPERANDS][SIZE_OF_LARGE_NUMBER];
+ /* Hold details of big operands. */
+FLONUM_TYPE float_operand[VIT_MAX_OPERANDS];
+ /* Above is made to point into */
+ /* big_operand_bits by md_begin(). */
+
+/*
+ * For VAX, relative addresses of "just the right length" are easy.
+ * The branch displacement is always the last operand, even in
+ * synthetic instructions.
+ * For VAX, we encode the relax_substateTs (in e.g. fr_substate) as:
+ *
+ * 4 3 2 1 0 bit number
+ * ---/ /--+-------+-------+-------+-------+-------+
+ * | what state ? | how long ? |
+ * ---/ /--+-------+-------+-------+-------+-------+
+ *
+ * The "how long" bits are 00=byte, 01=word, 10=long.
+ * This is a Un*x convention.
+ * Not all lengths are legit for a given value of (what state).
+ * The "how long" refers merely to the displacement length.
+ * The address usually has some constant bytes in it as well.
+ *
+
+groups for VAX address relaxing.
+
+1. "foo" pc-relative.
+ length of byte, word, long
+
+2a. J<cond> where <cond> is a simple flag test.
+ length of byte, word, long.
+ VAX opcodes are: (Hex)
+ bneq/bnequ 12
+ beql/beqlu 13
+ bgtr 14
+ bleq 15
+ bgeq 18
+ blss 19
+ bgtru 1a
+ blequ 1b
+ bvc 1c
+ bvs 1d
+ bgequ/bcc 1e
+ blssu/bcs 1f
+ Always, you complement 0th bit to reverse condition.
+ Always, 1-byte opcode, then 1-byte displacement.
+
+2b. J<cond> where cond tests a memory bit.
+ length of byte, word, long.
+ Vax opcodes are: (Hex)
+ bbs e0
+ bbc e1
+ bbss e2
+ bbcs e3
+ bbsc e4
+ bbcc e5
+ bbssi e6
+ bbcci e7
+ Always, you complement 0th bit to reverse condition.
+ Always, 1-byte opcde, longword-address, byte-address, 1-byte-displacement
+
+2c. J<cond> where cond tests low-order memory bit
+ length of byte,word,long.
+ Vax opcodes are: (Hex)
+ blbs e8
+ blbc e9
+ Always, you complement 0th bit to reverse condition.
+ Always, 1-byte opcode, longword-address, 1-byte displacement.
+
+3. Jbs/Jbr.
+ length of byte,word,long.
+ Vax opcodes are: (Hex)
+ bsbb 10
+ brb 11
+ These are like (2) but there is no condition to reverse.
+ Always, 1 byte opcode, then displacement/absolute.
+
+4a. JacbX
+ length of word, long.
+ Vax opcodes are: (Hex)
+ acbw 3d
+ acbf 4f
+ acbd 6f
+ abcb 9d
+ acbl f1
+ acbg 4ffd
+ acbh 6ffd
+ Always, we cannot reverse the sense of the branch; we have a word
+ displacement.
+ The double-byte op-codes don't hurt: we never want to modify the
+ opcode, so we don't care how many bytes are between the opcode and
+ the operand.
+
+4b. JXobXXX
+ length of long, long, byte.
+ Vax opcodes are: (Hex)
+ aoblss f2
+ aobleq f3
+ sobgeq f4
+ sobgtr f5
+ Always, we cannot reverse the sense of the branch; we have a byte
+ displacement.
+
+The only time we need to modify the opcode is for class 2 instructions.
+After relax() we may complement the lowest order bit of such instruction
+to reverse sense of branch.
+
+For class 2 instructions, we store context of "where is the opcode literal".
+We can change an opcode's lowest order bit without breaking anything else.
+
+We sometimes store context in the operand literal. This way we can figure out
+after relax() what the original addressing mode was.
+*/
+
+ /* 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.] */
+
+
+#define C(a,b) ENCODE_RELAX(a,b)
+ /* This macro has no side-effects. */
+#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
+
+const relax_typeS
+md_relax_table[] =
+{
+ {
+ 1, 1, 0, 0
+ }, /* error sentinel 0,0 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 0,1 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 0,2 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 0,3 */
+ {
+ BF + 1, BB + 1, 2, C (1, 1)
+ }, /* B^"foo" 1,0 */
+ {
+ WF + 1, WB + 1, 3, C (1, 2)
+ }, /* W^"foo" 1,1 */
+ {
+ 0, 0, 5, 0
+ }, /* L^"foo" 1,2 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 1,3 */
+ {
+ BF, BB, 1, C (2, 1)
+ }, /* b<cond> B^"foo" 2,0 */
+ {
+ WF + 2, WB + 2, 4, C (2, 2)
+ }, /* br.+? brw X 2,1 */
+ {
+ 0, 0, 7, 0
+ }, /* br.+? jmp X 2,2 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 2,3 */
+ {
+ BF, BB, 1, C (3, 1)
+ }, /* brb B^foo 3,0 */
+ {
+ WF, WB, 2, C (3, 2)
+ }, /* brw W^foo 3,1 */
+ {
+ 0, 0, 5, 0
+ }, /* Jmp L^foo 3,2 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 3,3 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 4,0 */
+ {
+ WF, WB, 2, C (4, 2)
+ }, /* acb_ ^Wfoo 4,1 */
+ {
+ 0, 0, 10, 0
+ }, /* acb_,br,jmp L^foo4,2 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 4,3 */
+ {
+ BF, BB, 1, C (5, 1)
+ }, /* Xob___,,foo 5,0 */
+ {
+ WF + 4, WB + 4, 6, C (5, 2)
+ }, /* Xob.+2,brb.+3,brw5,1 */
+ {
+ 0, 0, 9, 0
+ }, /* Xob.+2,brb.+6,jmp5,2 */
+};
+
+#undef C
+#undef BF
+#undef BB
+#undef WF
+#undef WB
+
+void float_cons ();
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"dfloat", float_cons, 'd'},
+ {"ffloat", float_cons, 'f'},
+ {"gfloat", float_cons, 'g'},
+ {"hfloat", float_cons, 'h'},
+ {0}
+};
+
+#define STATE_PC_RELATIVE (1)
+#define STATE_CONDITIONAL_BRANCH (2)
+#define STATE_ALWAYS_BRANCH (3) /* includes BSB... */
+#define STATE_COMPLEX_BRANCH (4)
+#define STATE_COMPLEX_HOP (5)
+
+#define STATE_BYTE (0)
+#define STATE_WORD (1)
+#define STATE_LONG (2)
+#define STATE_UNDF (3) /* Symbol undefined in pass1 */
+
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+
+void
+md_begin ()
+{
+ char *vip_begin ();
+ char *errtxt;
+ FLONUM_TYPE *fP;
+ int i;
+
+ if (*(errtxt = vip_begin (TRUE, "$", "*", "`")))
+ {
+ as_fatal ("VIP_BEGIN error:%s", errtxt);
+ }
+
+ for (i = 0, fP = float_operand;
+ fP < float_operand + VIT_MAX_OPERANDS;
+ i++, fP++)
+ {
+ fP->low = &big_operand_bits[i][0];
+ fP->high = &big_operand_bits[i][SIZE_OF_LARGE_NUMBER - 1];
+ }
+}
+
+void
+md_end ()
+{
+ vip_end ();
+}
+
+void /* Knows about order of bytes in address. */
+md_number_to_chars (con, value, nbytes)
+ char con[]; /* Return 'nbytes' of chars here. */
+ long int value; /* The value of the bits. */
+ int nbytes; /* Number of bytes in the output. */
+{
+ int n;
+ long 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_warn ("Displacement (%ld) long for instruction field length (%d).", v, n);
+}
+
+void /* Knows about order of bytes in address. */
+md_number_to_imm (con, value, nbytes)
+ char con[]; /* Return 'nbytes' of chars here. */
+ long int value; /* The value of the bits. */
+ int nbytes; /* Number of bytes in the output. */
+{
+ int n;
+ long 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_warn ("Displacement (%ld) too long for instruction field length (%d).", v, n);
+}
+
+void /* Knows about order of bytes in address. */
+md_number_to_disp (con, value, nbytes)
+ char con[]; /* Return 'nbytes' of chars here. */
+ long int value; /* The value of the bits. */
+ int nbytes; /* Number of bytes in the output. */
+{
+ abort ();
+ 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_warn ("Displacement too long for instruction field length.");
+}
+
+void /* Knows about order of bytes in address. */
+md_number_to_field (con, value, nbytes)
+ char con[]; /* Return 'nbytes' of chars here. */
+ long int value; /* The value of the bits. */
+ int nbytes; /* Number of bytes in the output. */
+{
+ abort ();
+ 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_warn ("Displacement too long for instruction field length.");
+}
+
+long int /* Knows about the byte order in a word. */
+md_chars_to_number (con, nbytes)
+ unsigned char con[]; /* Low order byte 1st. */
+ int nbytes; /* Number of bytes in the input. */
+{
+ long int retval;
+ for (retval = 0, con += nbytes - 1; nbytes--; con--)
+ {
+ retval <<= BITS_PER_CHAR;
+ retval |= *con;
+ }
+ return retval;
+}
+
+/* vax:md_assemble() emit frags for 1 instruction */
+
+void
+md_assemble (instruction_string)
+ char *instruction_string; /* A string: assemble 1 instruction. */
+{
+ char *p;
+ register struct vop *operandP;/* An operand. Scans all operands. */
+ char *save_input_line_pointer;
+ char c_save; /* What used to live after an expression. */
+ struct frag *fragP; /* Fragment of code we just made. */
+ register int goofed; /* TRUE: 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 */
+
+ /* 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 int opcode_as_number; /* As a number. */
+ char *opcode_as_chars; /* Least significant byte 1st. */
+ /* As an array of characters. */
+ char *opcode_low_byteP; /* Least significant byte 1st */
+ 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) */
+ 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);
+ }
+ /*
+ * Now we try to find as many as_warn()s as we can. If we do any as_warn()s
+ * then goofed=TRUE. Notice that we don't make any frags yet.
+ * Should goofed be TRUE, then this instruction will wedge in any pass,
+ * and we can safely flush it, without causing interpass symbol phase
+ * errors. That is, without changing label values in different passes.
+ */
+ if (goofed = (*v.vit_error))
+ {
+ as_warn ("Ignoring statement due to \"%s\"", v.vit_error);
+ }
+ /*
+ * We need to use expression() and friends, which require us to diddle
+ * input_line_pointer. So we save it and restore it later.
+ */
+ save_input_line_pointer = input_line_pointer;
+ for (operandP = v.vit_operand,
+ expP = exp_of_operand,
+ floatP = float_operand,
+ end_operandP = v.vit_operand + v.vit_operands;
+
+ operandP < end_operandP;
+
+ operandP++,
+ expP++,
+ floatP++
+ ) /* for each operand */
+ {
+ if (*(operandP->vop_error))
+ {
+ as_warn ("Ignoring statement because \"%s\"", (operandP->vop_error));
+ goofed = TRUE;
+ }
+ else
+ { /* statement has no syntax goofs: lets sniff the expression */
+ int can_be_short; /* TRUE if a bignum can be reduced to a short literal. */
+
+ input_line_pointer = operandP->vop_expr_begin;
+ 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 = TRUE. */
+ switch (to_seg = expression (expP))
+ {
+ case SEG_NONE:
+ /* for BSD4.2 compatibility, missing expression is absolute 0 */
+ to_seg = expP->X_seg = SEG_ABSOLUTE;
+ expP->X_add_number = 0;
+ /* for SEG_ABSOLUTE, we shouldnt need to set X_subtract_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:
+ break;
+
+ case SEG_DIFFERENCE:
+ case SEG_PASS1:
+ /*
+ * Major bug. We can't handle the case of a
+ * SEG_DIFFERENCE 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.
+ * 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
+ * .words after a CASE opcode, and was never intended for
+ * instruction operands.
+ */
+ need_pass_2 = TRUE;
+ as_warn("Can't relocate expression");
+ break;
+
+ case SEG_BIG:
+ /* Preserve the bits. */
+ if (expP->X_add_number > 0)
+ {
+ bignum_copy (generic_bignum, expP->X_add_number,
+ floatP->low, SIZE_OF_LARGE_NUMBER);
+ }
+ else
+ {
+ know (expP->X_add_number < 0);
+ flonum_copy (&generic_floating_point_number,
+ floatP);
+ if (index ("s i", operandP->vop_short))
+ { /* Could possibly become S^# */
+ flonum_gen2vax (-expP->X_add_number, floatP, literal_float);
+ switch (-expP->X_add_number)
+ {
+ case 'f':
+ can_be_short =
+ (literal_float[0] & 0xFC0F) == 0x4000
+ && literal_float[1] == 0;
+ break;
+
+ case 'd':
+ can_be_short =
+ (literal_float[0] & 0xFC0F) == 0x4000
+ && literal_float[1] == 0
+ && literal_float[2] == 0
+ && literal_float[3] == 0;
+ break;
+
+ case 'g':
+ can_be_short =
+ (literal_float[0] & 0xFF81) == 0x4000
+ && literal_float[1] == 0
+ && literal_float[2] == 0
+ && literal_float[3] == 0;
+ break;
+
+ case 'h':
+ can_be_short =
+ (literal_float[0] & 0xFFF8) == 0x4000
+ && (literal_float[1] & 0xE000) == 0
+ && literal_float[2] == 0
+ && literal_float[3] == 0
+ && literal_float[4] == 0
+ && literal_float[5] == 0
+ && literal_float[6] == 0
+ && literal_float[7] == 0;
+ break;
+
+ default:
+ BAD_CASE (-expP->X_add_number);
+ break;
+ } /* switch (float type) */
+ } /* if (could want to become S^#...) */
+ } /* bignum or flonum ? */
+
+ if (operandP->vop_short == 's'
+ || operandP->vop_short == 'i'
+ || (operandP->vop_short == ' '
+ && operandP->vop_reg == 0xF
+ && (operandP->vop_mode & 0xE) == 0x8))
+ {
+ /* Saw a '#'. */
+ if (operandP->vop_short == ' ')
+ { /* We must chose S^ or I^. */
+ if (expP->X_add_number > 0)
+ { /* Bignum: Short literal impossible. */
+ operandP->vop_short = 'i';
+ operandP->vop_mode = 8;
+ operandP->vop_reg = 0xF; /* VAX PC. */
+ }
+ else
+ { /* 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;
+ }
+ else
+ {
+ operandP->vop_short = 'i';
+ operandP->vop_mode = 8;
+ operandP->vop_reg = 0xF; /* VAX PC */
+ }
+ } /* bignum or flonum ? */
+ } /* if #, but no S^ or I^ seen. */
+ /* No more ' ' case: either 's' or 'i'. */
+ if (operandP->vop_short == 's')
+ {
+ /* Wants to be a short literal. */
+ if (expP->X_add_number > 0)
+ {
+ as_warn ("Bignum not permitted in short literal. Immediate mode assumed.");
+ operandP->vop_short = 'i';
+ operandP->vop_mode = 8;
+ operandP->vop_reg = 0xF; /* VAX PC. */
+ }
+ else
+ {
+ if (!can_be_short)
+ {
+ as_warn ("Can't do flonum short literal: immediate mode used.");
+ operandP->vop_short = 'i';
+ operandP->vop_mode = 8;
+ operandP->vop_reg = 0xF; /* VAX PC. */
+ }
+ else
+ { /* Encode short literal now. */
+ register int temp;
+
+ switch (-expP->X_add_number)
+ {
+ case 'f':
+ case 'd':
+ temp = literal_float[0] >> 4;
+ break;
+
+ case 'g':
+ temp = literal_float[0] >> 1;
+ break;
+
+ case 'h':
+ temp = ((literal_float[0] << 3) & 070)
+ | ((literal_float[1] >> 13) & 07);
+ break;
+
+ default:
+ BAD_CASE (-expP->X_add_number);
+ break;
+ }
+
+ floatP->low[0] = temp & 077;
+ floatP->low[1] = 0;
+ } /* if can be short literal float */
+ } /* flonum or bignum ? */
+ }
+ else
+ { /* I^# seen: set it up if float. */
+ if (expP->X_add_number < 0)
+ {
+ bcopy (literal_float, floatP->low, sizeof (literal_float));
+ }
+ } /* if S^# seen. */
+ }
+ else
+ {
+ as_warn ("A bignum/flonum may not be a displacement: 0x%x used",
+ expP->X_add_number = 0x80000000);
+ /* Chosen so luser gets the most offset bits to patch later. */
+ }
+ 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);
+ break;
+ }
+ if (input_line_pointer != operandP->vop_expr_end + 1)
+ {
+ as_warn ("Junk at end of expression \"%s\"", input_line_pointer);
+ goofed = TRUE;
+ }
+ operandP->vop_expr_end[1] = c_save;
+ }
+ } /* for(each operand) */
+ input_line_pointer = save_input_line_pointer;
+
+ if (!need_pass_2 && !goofed)
+ {
+ /* We saw no errors in any operands - try to make frag(s) */
+ int is_undefined; /* True if operand expression's */
+ /* segment not known yet. */
+ int length_code;
+
+ /* Emit op-code. */
+ /* Remember where it is, in case we want to modify the op-code later. */
+ opcode_low_byteP = frag_more (v.vit_opcode_nbytes);
+ bcopy (v.vit_opcode, opcode_low_byteP, v.vit_opcode_nbytes);
+ opcode_as_number = md_chars_to_number (opcode_as_chars = v.vit_opcode, 4);
+ for (operandP = v.vit_operand,
+ expP = exp_of_operand,
+ floatP = float_operand,
+ end_operandP = v.vit_operand + v.vit_operands;
+
+ operandP < end_operandP;
+
+ operandP++,
+ floatP++,
+ expP++
+ ) /* for each operand */
+ {
+ if (operandP->vop_ndx >= 0)
+ {
+ /* indexed addressing byte */
+ /* Legality of indexed mode already checked: it is OK */
+ FRAG_APPEND_1_CHAR (0x40 + operandP->vop_ndx);
+ } /* if(vop_ndx>=0) */
+
+ /* 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;
+ is_undefined = (to_seg == SEG_UNKNOWN);
+ know (to_seg == SEG_UNKNOWN \
+ ||to_seg == SEG_ABSOLUTE \
+ ||to_seg == SEG_DATA \
+ ||to_seg == SEG_TEXT \
+ ||to_seg == SEG_BSS \
+ ||to_seg == SEG_BIG \
+ );
+ at = operandP->vop_mode & 1;
+ length = operandP->vop_short == 'b' ? 1 : operandP->vop_short == 'w' ? 2 : operandP->vop_short == 'l' ? 4 : 0;
+ nbytes = operandP->vop_nbytes;
+ if (operandP->vop_access == 'b')
+ {
+ if (to_seg == now_seg || is_undefined)
+ { /* If is_undefined, then it might BECOME now_seg. */
+ if (nbytes)
+ {
+ p = frag_more (nbytes);
+ fix_new (frag_now, p - frag_now->fr_literal, nbytes,
+ this_add_symbol, 0, this_add_number, 1);
+ }
+ else
+ { /* to_seg==now_seg || to_seg == SEG_UNKNOWN */
+ /* nbytes==0 */
+ length_code = is_undefined ? STATE_UNDF : STATE_BYTE;
+ if (opcode_as_number & VIT_OPCODE_SPECIAL)
+ {
+ if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP)
+ {
+ /* br or jsb */
+ frag_var (rs_machine_dependent, 5, 1,
+ ENCODE_RELAX (STATE_ALWAYS_BRANCH, length_code),
+ this_add_symbol, this_add_number,
+ opcode_low_byteP);
+ }
+ else
+ {
+ if (operandP->vop_width == VAX_WIDTH_WORD_JUMP)
+ {
+ length_code = STATE_WORD; /* JF: There is no state_byte for this one! */
+ frag_var (rs_machine_dependent, 10, 2,
+ ENCODE_RELAX (STATE_COMPLEX_BRANCH, length_code),
+ this_add_symbol, this_add_number,
+ opcode_low_byteP);
+ }
+ else
+ {
+ know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP);
+ frag_var (rs_machine_dependent, 9, 1,
+ ENCODE_RELAX (STATE_COMPLEX_HOP, length_code),
+ this_add_symbol, this_add_number,
+ opcode_low_byteP);
+ }
+ }
+ }
+ else
+ {
+ know (operandP->vop_width == VAX_WIDTH_CONDITIONAL_JUMP);
+ frag_var (rs_machine_dependent, 7, 1,
+ ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, length_code),
+ this_add_symbol, this_add_number,
+ opcode_low_byteP);
+ }
+ }
+ }
+ else
+ { /* to_seg != now_seg && to_seg != SEG_UNKNOWN */
+/*
+ * --- SEG FLOAT MAY APPEAR HERE ----
+ */
+ if (to_seg == SEG_ABSOLUTE)
+ {
+ if (nbytes)
+ {
+ know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC));
+ p = frag_more (nbytes);
+ /* Conventional relocation. */
+ fix_new (frag_now, p - frag_now->fr_literal,
+ nbytes, &abs_symbol, 0, this_add_number, 1);
+ }
+ else
+ {
+ know (opcode_as_number & VIT_OPCODE_SYNTHETIC);
+ if (opcode_as_number & VIT_OPCODE_SPECIAL)
+ {
+ if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP)
+ {
+ /* br or jsb */
+ *opcode_low_byteP = opcode_as_chars[0] + VAX_WIDEN_LONG;
+ know (opcode_as_chars[1] == 0);
+ p = frag_more (5);
+ p[0] = VAX_ABSOLUTE_MODE; /* @#... */
+ md_number_to_chars (p + 1, this_add_number, 4);
+ /* Now (eg) JMP @#foo or JSB @#foo. */
+ }
+ else
+ {
+ if (operandP->vop_width == VAX_WIDTH_WORD_JUMP)
+ {
+ p = frag_more (10);
+ p[0] = 2;
+ p[1] = 0;
+ p[2] = VAX_BRB;
+ p[3] = 6;
+ p[4] = VAX_JMP;
+ 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:
+ */
+ }
+ else
+ {
+ know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP);
+ p = frag_more (9);
+ p[0] = 2;
+ p[1] = VAX_BRB;
+ p[2] = 6;
+ p[3] = VAX_JMP;
+ 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:
+ */
+ }
+ }
+ }
+ else
+ {
+ /* b<cond> */
+ *opcode_low_byteP ^= 1; /* 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:
+ */
+ }
+ }
+ }
+ else
+ { /* 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);
+ }
+ else
+ {
+ know (opcode_as_number & VIT_OPCODE_SYNTHETIC);
+ if (opcode_as_number & VIT_OPCODE_SPECIAL)
+ {
+ if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP)
+ {
+ /* br or jsb */
+ know (opcode_as_chars[1] == 0);
+ *opcode_low_byteP = opcode_as_chars[0] + VAX_WIDEN_LONG;
+ p = frag_more (5);
+ p[0] = VAX_PC_RELATIVE_MODE;
+ fix_new (frag_now,
+ p + 1 - frag_now->fr_literal, 4,
+ this_add_symbol, 0,
+ this_add_number, 1);
+ /* Now eg JMP foo or JSB foo. */
+ }
+ else
+ {
+ if (operandP->vop_width == VAX_WIDTH_WORD_JUMP)
+ {
+ p = frag_more (10);
+ p[0] = 0;
+ p[1] = 2;
+ p[2] = VAX_BRB;
+ p[3] = 6;
+ p[4] = VAX_JMP;
+ p[5] = VAX_PC_RELATIVE_MODE;
+ fix_new (frag_now,
+ p + 6 - frag_now->fr_literal, 4,
+ this_add_symbol, 0,
+ this_add_number, 1);
+ /*
+ * Now (eg) ACBx 1f
+ * BRB 2f
+ * 1: JMP foo
+ * 2:
+ */
+ }
+ else
+ {
+ know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP);
+ p = frag_more (10);
+ p[0] = 2;
+ p[1] = VAX_BRB;
+ p[2] = 6;
+ p[3] = VAX_JMP;
+ p[4] = VAX_PC_RELATIVE_MODE;
+ fix_new (frag_now,
+ p + 5 - frag_now->fr_literal,
+ 4, this_add_symbol, 0,
+ this_add_number, 1);
+ /*
+ * Now (eg) xOBxxx 1f
+ * BRB 2f
+ * 1: JMP foo
+ * 2:
+ */
+ }
+ }
+ }
+ else
+ {
+ know (operandP->vop_width == VAX_WIDTH_CONDITIONAL_JUMP);
+ *opcode_low_byteP ^= 1; /* Reverse branch condition. */
+ p = frag_more (7);
+ p[0] = 6;
+ 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,
+ this_add_number, 1);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ know (operandP->vop_access != 'b'); /* So it is ordinary operand. */
+ know (operandP->vop_access != ' '); /* ' ' target-independent: elsewhere. */
+ know (operandP->vop_access == 'a' || operandP->vop_access == 'm' || operandP->vop_access == 'r' || operandP->vop_access == 'v' || operandP->vop_access == 'w');
+ if (operandP->vop_short == 's')
+ {
+ if (to_seg == SEG_ABSOLUTE)
+ {
+ if (this_add_number < 0 || this_add_number >= 64)
+ {
+ as_warn ("Short literal overflow(%d.), immediate mode assumed.", this_add_number);
+ operandP->vop_short = 'i';
+ operandP->vop_mode = 8;
+ operandP->vop_reg = 0xF;
+ }
+ }
+ else
+ {
+ as_warn ("Forced short literal to immediate mode. now_seg=%s to_seg=%s", seg_name[(int) now_seg], seg_name[(int) to_seg]);
+ operandP->vop_short = 'i';
+ operandP->vop_mode = 8;
+ operandP->vop_reg = 0xF;
+ }
+ }
+ if (operandP->vop_reg >= 0 && (operandP->vop_mode < 8 || (operandP->vop_reg != 0xF && operandP->vop_mode < 10)))
+ { /* One byte operand. */
+ know (operandP->vop_mode > 3);
+ FRAG_APPEND_1_CHAR (operandP->vop_mode << 4 | operandP->vop_reg);
+ /* All 1-bytes except S^# happen here. */
+ }
+ else
+ { /* {@}{q^}foo{(Rn)} or S^#foo */
+ if (operandP->vop_reg == -1 && operandP->vop_short != 's')
+ { /* "{@}{q^}foo" */
+ if (to_seg == now_seg)
+ {
+ if (length == 0)
+ {
+ know (operandP->vop_short == ' ');
+ p = frag_var (rs_machine_dependent, 10, 2,
+ ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE),
+ this_add_symbol, this_add_number,
+ 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. */
+ }
+ 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,
+ this_add_number, 1);
+ }
+ }
+ else
+ { /* to_seg != now_seg */
+ if (this_add_symbol == NULL)
+ {
+ know (to_seg == SEG_ABSOLUTE);
+ /* Do @#foo: simpler relocation than foo-.(pc) anyway. */
+ p = frag_more (5);
+ p[0] = VAX_ABSOLUTE_MODE; /* @#... */
+ md_number_to_chars (p + 1, this_add_number, 4);
+ if (length && length != 4)
+ {
+ as_warn ("Length specification ignored. Address mode 9F used");
+ }
+ }
+ else
+ {
+ /* {@}{q^}other_seg */
+ know ((length == 0 && operandP->vop_short == ' ') \
+ ||(length > 0 && operandP->vop_short != ' '));
+ if (is_undefined)
+ {
+ /*
+ * 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,
+ 0);
+ p[0] = at << 4;
+ }
+ else
+ {
+ if (length == 0)
+ {
+ know (operandP->vop_short == ' ');
+ length = 4; /* Longest possible. */
+ }
+ p = frag_more (length + 1);
+ p[0] = 0xF | ((at + "?\12\14?\16"[length]) << 4);
+ 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,
+ this_add_number, 1);
+ }
+ }
+ }
+ }
+ else
+ { /* {@}{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 != ' ')); */
+ if (length == 0
+ && to_seg == SEG_ABSOLUTE
+ && operandP->vop_mode == 8 /* No '@'. */
+ && this_add_number < 64
+ && this_add_number >= 0)
+ {
+ operandP->vop_short = 's';
+ }
+ if (operandP->vop_short == 's')
+ {
+ FRAG_APPEND_1_CHAR (this_add_number);
+ }
+ else
+ { /* I^#... */
+ know (nbytes);
+ p = frag_more (nbytes + 1);
+ know (operandP->vop_reg == 0xF);
+ p[0] = (operandP->vop_mode << 4) | 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.
+ */
+ md_number_to_chars (p + 1, this_add_number, min (4, nbytes));
+ if (nbytes > 4)
+ {
+ bzero (p + 5, nbytes - 4);
+ }
+ }
+ else
+ {
+ if (to_seg == SEG_BIG)
+ {
+/*
+ * 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;
+ if (nbytes & 1)
+ {
+ know (nbytes == 1);
+ p[1] = *lP;
+ }
+ else
+ {
+ for (p++; nbytes; nbytes -= 2, p += 2, lP++)
+ {
+ md_number_to_chars (p, *lP, 2);
+ }
+ }
+ }
+ else
+ {
+ fix_new (frag_now, p + 1 - frag_now->fr_literal,
+ nbytes, this_add_symbol, 0,
+ this_add_number, 0);
+ }
+ }
+ }
+ }
+ else
+ { /* {@}{q^}foo(Rn) */
+ know ((length == 0 && operandP->vop_short == ' ') \
+ ||(length > 0 && operandP->vop_short != ' '));
+ if (length == 0)
+ {
+ if (to_seg == SEG_ABSOLUTE)
+ {
+ register long int test;
+
+ test = this_add_number;
+
+ if (test < 0)
+ test = ~test;
+
+ length = test & 0xffff8000 ? 4
+ : test & 0xffffff80 ? 2
+ : 1;
+ }
+ else
+ {
+ length = 4;
+ }
+ }
+ p = frag_more (1 + length);
+ know (operandP->vop_reg >= 0);
+ p[0] = operandP->vop_reg
+ | ((at | "?\12\14?\16"[length]) << 4);
+ if (to_seg == SEG_ABSOLUTE)
+ {
+ md_number_to_chars (p + 1, this_add_number, length);
+ }
+ else
+ {
+ fix_new (frag_now, p + 1 - frag_now->fr_literal,
+ length, this_add_symbol, 0,
+ this_add_number, 0);
+ }
+ }
+ }
+ } /* if(single-byte-operand) */
+ }
+ } /* for(operandP) */
+ } /* if(!need_pass_2&&!goofed) */
+} /* vax_assemble() */
+
+/*
+ * md_estimate_size_before_relax()
+ *
+ * Called just before relax().
+ * Any symbol that is now undefined will not become defined.
+ * Return the correct fr_subtype in the frag.
+ * Return the initial "guess for fr_var" to caller.
+ * The guess for fr_var is ACTUALLY the growth beyond fr_fix.
+ * Whatever we do to grow fr_fix or fr_var contributes to our returned value.
+ * Although it may not be explicit in the frag, pretend fr_var starts with a
+ * 0 value.
+ */
+int
+md_estimate_size_before_relax (fragP, segment_type)
+ register fragS *fragP;
+ register int segment_type; /* N_DATA or N_TEXT. */
+{
+ register char *p;
+ register int old_fr_fix;
+
+ old_fr_fix = fragP->fr_fix;
+ switch (fragP->fr_subtype)
+ {
+ case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):
+ if ((fragP->fr_symbol->sy_type & N_TYPE) == segment_type)
+ { /* A relaxable case. */
+ fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
+ }
+ else
+ {
+ 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,
+ fragP->fr_offset, 1);
+ frag_wane (fragP);
+ }
+ break;
+
+ case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):
+ if ((fragP->fr_symbol->sy_type & N_TYPE) == segment_type)
+ {
+ fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE);
+ }
+ else
+ {
+ p = fragP->fr_literal + old_fr_fix;
+ *fragP->fr_opcode ^= 1; /* Reverse sense of branch. */
+ p[0] = 6;
+ 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,
+ fragP->fr_offset, 1);
+ frag_wane (fragP);
+ }
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_UNDF):
+ if ((fragP->fr_symbol->sy_type & N_TYPE) == segment_type)
+ {
+ fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD);
+ }
+ else
+ {
+ p = fragP->fr_literal + old_fr_fix;
+ p[0] = 2;
+ p[1] = 0;
+ p[2] = VAX_BRB;
+ p[3] = 6;
+ 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,
+ fragP->fr_offset, 1);
+ frag_wane (fragP);
+ }
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_UNDF):
+ if ((fragP->fr_symbol->sy_type & N_TYPE) == segment_type)
+ {
+ fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE);
+ }
+ else
+ {
+ p = fragP->fr_literal + old_fr_fix;
+ p[0] = 2;
+ p[1] = VAX_BRB;
+ p[2] = 6;
+ 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,
+ fragP->fr_offset, 1);
+ frag_wane (fragP);
+ }
+ break;
+
+ case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_UNDF):
+ if ((fragP->fr_symbol->sy_type & N_TYPE) == segment_type)
+ {
+ fragP->fr_subtype = ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE);
+ }
+ else
+ {
+ p = fragP->fr_literal + old_fr_fix;
+ *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,
+ fragP->fr_offset, 1);
+ frag_wane (fragP);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
+} /* md_estimate_size_before_relax() */
+
+/*
+ * md_convert_frag();
+ *
+ * Called after relax() is finished.
+ * In: Address of frag.
+ * fr_type == rs_machine_dependent.
+ * fr_subtype is what the address relaxed to.
+ *
+ * Out: Any fixSs and constants are set up.
+ * Caller will turn frag into a ".space 0".
+ */
+void
+md_convert_frag (fragP)
+ register fragS *fragP;
+{
+ register char *addressP; /* -> _var to change. */
+ register char *opcodeP; /* -> opcode char(s) to change. */
+ register short int length_code; /* 2=long 1=word 0=byte */
+ register short int extension; /* Size of relaxed address. */
+ /* Added to fr_fix: incl. ALL var chars. */
+ register symbolS *symbolP;
+ register long int where;
+ register long int address_of_var;
+ /* Where, in file space, is _var of *fragP? */
+ register long int target_address;
+ /* Where, in file space, does addr point? */
+
+ know (fragP->fr_type == rs_machine_dependent);
+ length_code = fragP->fr_subtype & 3; /* depends on ENCODE_RELAX() */
+ know (length_code >= 0 && length_code < 3);
+ where = fragP->fr_fix;
+ addressP = fragP->fr_literal + where;
+ opcodeP = fragP->fr_opcode;
+ symbolP = fragP->fr_symbol;
+ know (symbolP);
+ target_address = symbolP->sy_value + fragP->fr_offset;
+ address_of_var = fragP->fr_address + where;
+ switch (fragP->fr_subtype)
+ {
+ case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
+ know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */
+ addressP[0] |= 0xAF; /* Byte displacement. */
+ addressP[1] = target_address - (address_of_var + 2);
+ extension = 2;
+ break;
+
+ case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
+ know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */
+ addressP[0] |= 0xCF; /* Word displacement. */
+ md_number_to_chars (addressP + 1, target_address - (address_of_var + 3), 2);
+ extension = 3;
+ break;
+
+ case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_LONG):
+ know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */
+ addressP[0] |= 0xEF; /* Long word displacement. */
+ md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4);
+ extension = 5;
+ break;
+
+ case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
+ addressP[0] = target_address - (address_of_var + 1);
+ extension = 1;
+ break;
+
+ case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
+ opcodeP[0] ^= 1; /* Reverse sense of test. */
+ addressP[0] = 3;
+ addressP[1] = VAX_BRB + VAX_WIDEN_WORD;
+ md_number_to_chars (addressP + 2, target_address - (address_of_var + 4), 2);
+ extension = 4;
+ break;
+
+ case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_LONG):
+ opcodeP[0] ^= 1; /* Reverse sense of test. */
+ addressP[0] = 6;
+ addressP[1] = VAX_JMP;
+ addressP[2] = VAX_PC_RELATIVE_MODE;
+ md_number_to_chars (addressP + 3, target_address, 4);
+ extension = 7;
+ break;
+
+ case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE):
+ addressP[0] = target_address - (address_of_var + 1);
+ extension = 1;
+ break;
+
+ case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_WORD):
+ opcodeP[0] += VAX_WIDEN_WORD; /* brb -> brw, bsbb -> bsbw */
+ md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
+ extension = 2;
+ break;
+
+ case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_LONG):
+ opcodeP[0] += VAX_WIDEN_LONG; /* brb -> jmp, bsbb -> jsb */
+ addressP[0] = VAX_PC_RELATIVE_MODE;
+ md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4);
+ extension = 5;
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD):
+ md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
+ extension = 2;
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_LONG):
+ addressP[0] = 2;
+ addressP[1] = 0;
+ addressP[2] = VAX_BRB;
+ addressP[3] = 6;
+ addressP[4] = VAX_JMP;
+ addressP[5] = VAX_PC_RELATIVE_MODE;
+ md_number_to_chars (addressP + 6, target_address, 4);
+ extension = 10;
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE):
+ addressP[0] = target_address - (address_of_var + 1);
+ extension = 1;
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_WORD):
+ addressP[0] = 2;
+ addressP[1] = VAX_BRB;
+ addressP[2] = 3;
+ addressP[3] = VAX_BRW;
+ md_number_to_chars (addressP + 4, target_address - (address_of_var + 6), 2);
+ extension = 6;
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_LONG):
+ addressP[0] = 2;
+ addressP[1] = VAX_BRB;
+ addressP[2] = 6;
+ addressP[3] = VAX_JMP;
+ addressP[4] = VAX_PC_RELATIVE_MODE;
+ md_number_to_chars (addressP + 5, target_address, 4);
+ extension = 9;
+ break;
+
+ default:
+ BAD_CASE (fragP->fr_subtype);
+ break;
+ }
+ fragP->fr_fix += extension;
+}
+
+/* the bit-field entries in the relocation_info struct plays hell
+ with the byte-order problems of cross-assembly. So as a hack,
+ I added this mach. dependent ri twiddler. Ugly, but it gets
+ you there. -KWK */
+/* on vax: first 4 bytes are normal unsigned long, next three bytes
+ are symbolnum, least sig. byte first. Last byte is broken up with
+ the upper nibble as nuthin, bit 3 as extern, bits 2 & 1 as length, and
+ bit 0 as pcrel. */
+void
+md_ri_to_chars (ri_p, ri)
+ struct relocation_info *ri_p, ri;
+{
+ unsigned char the_bytes[8];
+
+ /* this is easy */
+ md_number_to_chars (the_bytes, ri.r_address, sizeof (ri.r_address));
+ /* now the fun stuff */
+ the_bytes[6] = (ri.r_symbolnum >> 16) & 0x0ff;
+ the_bytes[5] = (ri.r_symbolnum >> 8) & 0x0ff;
+ the_bytes[4] = ri.r_symbolnum & 0x0ff;
+ the_bytes[7] = (((ri.r_extern << 3) & 0x08) | ((ri.r_length << 1) & 0x06) |
+ ((ri.r_pcrel << 0) & 0x01)) & 0x0F;
+ /* now put it back where you found it */
+ bcopy (the_bytes, (char *) ri_p, sizeof (struct relocation_info));
+}
+
+
+
+ /* JF this used to be a separate file */
+/* vax_ins_parse.c - a part for a VAX assembler */
+
+/* Copyright (C) 1987 Free Software Foundtation, Inc */
+
+/*
+ * BUGS, GRIPES, APOLOGIA, etc.
+ *
+ * The opcode table 'votstrs' needs to be sorted on opcode frequency.
+ * 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.
+ */
+
+/*
+ * This is a vaguely modular set of routines in C to parse VAX
+ * assembly code using DEC mnemonics. It is NOT un*x specific.
+ *
+ * The idea here is that the assembler has taken care of all:
+ * labels
+ * macros
+ * listing
+ * pseudo-ops
+ * line continuation
+ * comments
+ * condensing any whitespace down to exactly one space
+ * and all we have to do is parse 1 line into a vax instruction
+ * partially formed. We will accept a line, and deliver:
+ * an error message (hopefully empty)
+ * a skeleton VAX instruction (tree structure)
+ * textual pointers to all the operand expressions
+ * a warning message that notes a silly operand (hopefully empty)
+ */
+
+/*
+ * E D I T H I S T O R Y
+ *
+ * 17may86 Dean Elsner. Bug if line ends immediately after opcode.
+ * 30apr86 Dean Elsner. New vip_op() uses arg block so change call.
+ * 6jan86 Dean Elsner. Crock vip_begin() to call vip_op_defaults().
+ * 2jan86 Dean Elsner. Invent synthetic opcodes.
+ * Widen vax_opcodeT to 32 bits. Use a bit for VIT_OPCODE_SYNTHETIC,
+ * which means this is not a real opcode, it is like a macro; it will
+ * be relax()ed into 1 or more instructions.
+ * Use another bit for VIT_OPCODE_SPECIAL if the op-code is not optimised
+ * like a regular branch instruction. Option added to vip_begin():
+ * exclude synthetic opcodes. Invent synthetic_votstrs[].
+ * 31dec85 Dean Elsner. Invent vit_opcode_nbytes.
+ * Also make vit_opcode into a char[]. We now have n-byte vax opcodes,
+ * so caller's don't have to know the difference between a 1-byte & a
+ * 2-byte op-code. Still need vax_opcodeT concept, so we know how
+ * big an object must be to hold an op.code.
+ * 30dec85 Dean Elsner. Widen typedef vax_opcodeT in "vax-inst.h"
+ * because vax opcodes may be 16 bits. Our crufty C compiler was
+ * happily initialising 8-bit vot_codes with 16-bit numbers!
+ * (Wouldn't the 'phone company like to compress data so easily!)
+ * 29dec85 Dean Elsner. New static table vax_operand_width_size[].
+ * Invented so we know hw many bytes a "I^#42" needs in its immediate
+ * operand. Revised struct vop in "vax-inst.h": explicitly include
+ * byte length of each operand, and it's letter-code datum type.
+ * 17nov85 Dean Elsner. Name Change.
+ * Due to ar(1) truncating names, we learned the hard way that
+ * "vax-inst-parse.c" -> "vax-inst-parse." dropping the "o" off
+ * the archived object name. SO... we shortened the name of this
+ * source file, and changed the makefile.
+ */
+
+/* #include <stdio.h> JF for one big happy file */
+
+/* JF #include "vax-inst.h" /* define the tree we parse it into */
+
+
+static char *op_hash = NULL; /* handle of the OPCODE hash table */
+ /* NULL means any use before vip_begin() */
+ /* will crash */
+
+/*
+ * In: 1 character, from "bdfghloqpw" being the data-type of an operand
+ * of a vax instruction.
+ *
+ * Out: the length of an operand of that type, in bytes.
+ * Special branch operands types "-?!" have length 0.
+ */
+
+static const short int vax_operand_width_size[256] =
+{
+
+#define _ 0
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+ _, _, 1, _, 8, _, 4, 8, 16, _, _, _, 4, _, _, 16, /* ..b.d.fgh...l..o */
+ _, 8, _, _, _, _, _, 2, _, _, _, _, _, _, _, _, /* .q.....w........ */
+ _, _, 1, _, 8, _, 4, 8, 16, _, _, _, 4, _, _, 16, /* ..b.d.fgh...l..o */
+ _, 8, _, _, _, _, _, 2, _, _, _, _, _, _, _, _, /* .q.....w........ */
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _};
+#undef _
+
+/*
+ * This perversion encodes all the vax opcodes as a bunch of strings.
+ * RMS says we should build our hash-table at run-time. Hmm.
+ * Please would someone arrange these in decreasing frequency of opcode?
+ * Because of the way hash_...() works, the most frequently used opcode
+ * should be textually first and so on.
+ *
+ * Input for this table was 'vax.opcodes', awk(1)ed by 'vax.opcodes.c.awk' .
+ * So change 'vax.opcodes', then re-generate this table.
+ */
+
+#include "vax-opcode.h"
+
+/*
+ * This is a table of optional op-codes. All of them represent
+ * 'synthetic' instructions that seem popular.
+ *
+ * Here we make some pseudo op-codes. Every code has a bit set to say
+ * it is synthetic. This lets you catch them if you want to
+ * ban these opcodes. They are mnemonics for "elastic" instructions
+ * that are supposed to assemble into the fewest bytes needed to do a
+ * branch, or to do a conditional branch, or whatever.
+ *
+ * The opcode is in the usual place [low-order n*8 bits]. This means
+ * that if you mask off the bucky bits, the usual rules apply about
+ * how long the opcode is.
+ *
+ * All VAX branch displacements come at the end of the instruction.
+ * For simple branches (1-byte opcode + 1-byte displacement) the last
+ * operand is coded 'b?' where the "data type" '?' is a clue that we
+ * may reverse the sense of the branch (complement lowest order bit)
+ * and branch around a jump. This is by far the most common case.
+ * That is why the VIT_OPCODE_SYNTHETIC bit is set: it says this is
+ * a 0-byte op-code followed by 2 or more bytes of operand address.
+ *
+ * If the op-code has VIT_OPCODE_SPECIAL set, then we have a more unusual
+ * case.
+ *
+ * For JBSB & JBR the treatment is the similar, except (1) we have a 'bw'
+ * option before (2) we can directly JSB/JMP because there is no condition.
+ * These operands have 'b-' as their access/data type.
+ *
+ * That leaves a bunch of random opcodes: JACBx, JxOBxxx. In these
+ * cases, we do the same idea. JACBxxx are all marked with a 'b!'
+ * JAOBxxx & JSOBxxx are marked with a 'b:'.
+ *
+ */
+#if (VIT_OPCODE_SYNTHETIC != 0x80000000)
+You have just broken the encoding below, which assumes the sign bit
+ means 'I am an imaginary instruction'.
+#endif
+
+#if (VIT_OPCODE_SPECIAL != 0x40000000)
+ You have just broken the encoding below, which assumes the 0x40 M bit means
+ 'I am not to be "optimised" the way normal branches are'.
+#endif
+
+static const struct vot
+ synthetic_votstrs[] =
+{
+ {"jbsb",
+ {"b-", 0xC0000010}}, /* BSD 4.2 */
+ /* jsb used already */
+ {"jbr",
+ {"b-", 0xC0000011}}, /* BSD 4.2 */
+ {"jr",
+ {"b-", 0xC0000011}}, /* consistent */
+ {"jneq",
+ {"b?", 0x80000012}},
+ {"jnequ",
+ {"b?", 0x80000012}},
+ {"jeql",
+ {"b?", 0x80000013}},
+ {"jeqlu",
+ {"b?", 0x80000013}},
+ {"jgtr",
+ {"b?", 0x80000014}},
+ {"jleq",
+ {"b?", 0x80000015}},
+ /* un-used opcodes here */
+ {"jgeq",
+ {"b?", 0x80000018}},
+ {"jlss",
+ {"b?", 0x80000019}},
+ {"jgtru",
+ {"b?", 0x8000001a}},
+ {"jlequ",
+ {"b?", 0x8000001b}},
+ {"jvc",
+ {"b?", 0x8000001c}},
+ {"jvs",
+ {"b?", 0x8000001d}},
+ {"jgequ",
+ {"b?", 0x8000001e}},
+ {"jcc",
+ {"b?", 0x8000001e}},
+ {"jlssu",
+ {"b?", 0x8000001f}},
+ {"jcs",
+ {"b?", 0x8000001f}},
+
+ {"jacbw",
+ {"rwrwmwb!", 0xC000003d}},
+ {"jacbf",
+ {"rfrfmfb!", 0xC000004f}},
+ {"jacbd",
+ {"rdrdmdb!", 0xC000006f}},
+ {"jacbb",
+ {"rbrbmbb!", 0xC000009d}},
+ {"jacbl",
+ {"rlrlmlb!", 0xC00000f1}},
+ {"jacbg",
+ {"rgrgmgb!", 0xC0004ffd}},
+ {"jacbh",
+ {"rhrhmhb!", 0xC0006ffd}},
+
+ {"jbs",
+ {"rlvbb?", 0x800000e0}},
+ {"jbc",
+ {"rlvbb?", 0x800000e1}},
+ {"jbss",
+ {"rlvbb?", 0x800000e2}},
+ {"jbcs",
+ {"rlvbb?", 0x800000e3}},
+ {"jbsc",
+ {"rlvbb?", 0x800000e4}},
+ {"jbcc",
+ {"rlvbb?", 0x800000e5}},
+ {"jbssi",
+ {"rlvbb?", 0x800000e6}},
+ {"jbcci",
+ {"rlvbb?", 0x800000e7}},
+ {"jlbs",
+ {"rlb?", 0x800000e8}}, /* JF changed from rlvbb? */
+ {"jlbc",
+ {"rlb?", 0x800000e9}}, /* JF changed from rlvbb? */
+
+ {"jaoblss",
+ {"rlmlb:", 0xC00000f2}},
+ {"jaobleq",
+ {"rlmlb:", 0xC00000f3}},
+ {"jsobgeq",
+ {"mlb:", 0xC00000f4}}, /* JF was rlmlb: */
+ {"jsobgtr",
+ {"mlb:", 0xC00000f5}}, /* JF was rlmlb: */
+
+/* CASEx has no branch addresses in our conception of it. */
+/* You should use ".word ..." statements after the "case ...". */
+
+ {"", ""} /* empty is end sentinel */
+
+}; /* synthetic_votstrs */
+
+/*
+ * v i p _ b e g i n ( )
+ *
+ * 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 "".
+ * If you want, I will include the 'synthetic' jXXX instructions in the
+ * instruction table.
+ * You must nominate metacharacters for eg DEC's "#", "@", "^".
+ */
+
+char *
+vip_begin (synthetic_too, immediate, indirect, displen)
+ int synthetic_too; /* TRUE means include jXXX op-codes. */
+ char *immediate, *indirect, *displen;
+{
+ register const struct vot *vP; /* scan votstrs */
+ register char *retval; /* error text */
+
+ char *hash_insert (); /* */
+ char *hash_new (); /* lies */
+
+ 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);
+}
+
+
+/*
+ * 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.
+ */
+vip_end ()
+{
+}
+
+/*
+ * v i p ( )
+ *
+ * This converts a string into a vax instruction.
+ * The string must be a bare single instruction in dec-vax (with BSD4 frobs)
+ * format.
+ * It provides some error messages: at most one fatal error message (which
+ * stops the scan) and at most one warning message for each operand.
+ * The vax instruction is returned in exploded form, since we have no
+ * knowledge of how you parse (or evaluate) your expressions.
+ * We do however strip off and decode addressing modes and operation
+ * mnemonic.
+ *
+ * The exploded instruction is returned to a struct vit of your choice.
+ * #include "vax-inst.h" to know what a struct vit is.
+ *
+ * This function's value is a string. If it is not "" then an internal
+ * logic error was found: read this code to assign meaning to the string.
+ * 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.
+ */
+
+char * /* "" or bug string */
+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. */
+
+ struct vot_wot *hash_find ();
+ char *vip_op ();
+
+ bug = "";
+ if (*instring == ' ')
+ ++instring; /* Skip leading whitespace. */
+ for (p = instring; *p && *p != ' '; p++)
+ ; /* MUST end in end-of-string or exactly 1 space. */
+ /* Scanned up to end of operation-code. */
+ /* Operation-code is ended with whitespace. */
+ if (p - instring == 0)
+ {
+ vitP->vit_error = "No operator";
+ count = 0;
+ bzero (vitP->vit_opcode, sizeof (vitP->vit_opcode));
+ }
+ else
+ {
+ c = *p;
+ *p = '\0';
+ /*
+ * Here with instring pointing to what better be an op-name, and p
+ * pointing to character just past that.
+ * We trust instring points to an op-name, with no whitespace.
+ */
+ vwP = hash_find (op_hash, instring);
+ *p = c; /* Restore char after op-code. */
+ if (vwP == 0)
+ {
+ vitP->vit_error = "Unknown operator";
+ count = 0;
+ bzero (vitP->vit_opcode, sizeof (vitP->vit_opcode));
+ }
+ else
+ {
+ /*
+ * We found a match! So lets pick up as many operands as the
+ * instruction wants, and even gripe if there are too many.
+ * We expect comma to seperate each operand.
+ * We let instring track the text, while p tracks a part of the
+ * struct vot.
+ */
+ /*
+ * The lines below know about 2-byte opcodes starting FD,FE or FF.
+ * They also understand synthetic opcodes. Note:
+ * we return 32 bits of opcode, including bucky bits, BUT
+ * an opcode length is either 8 or 16 bits for vit_opcode_nbytes.
+ */
+ oc = vwP->vot_code; /* The op-code. */
+ vitP->vit_opcode_nbytes = (oc & 0xFF) >= 0xFD ? 2 : 1;
+ md_number_to_chars (vitP->vit_opcode, oc, 4);
+ count = 0; /* no operands seen yet */
+ instring = p; /* point just past operation code */
+ alloperr = "";
+ for (p = vwP->vot_how, operandp = vitP->vit_operand;
+ !*alloperr && !*bug && *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?? */
+ else if (*instring)
+ {
+ for (q = instring; (c = *q) && c != ','; q++)
+ ;
+ /*
+ * Q points to ',' or '\0' that ends argument. C is that
+ * character.
+ */
+ *q = 0;
+ operandp->vop_width = p[1];
+ operandp->vop_nbytes = vax_operand_width_size[p[1]];
+ operandp->vop_access = p[0];
+ bug = vip_op (instring, operandp);
+ *q = c; /* Restore input text. */
+ if (*(operandp->vop_error))
+ alloperr = "Bad operand";
+ instring = q + (c ? 1 : 0); /* next operand (if any) */
+ count++; /* won another argument, may have an operr */
+ }
+ else
+ alloperr = "Not enough operands";
+ }
+ if (!*alloperr)
+ {
+ if (*instring == ' ')
+ instring++; /* Skip whitespace. */
+ if (*instring)
+ alloperr = "Too many operands";
+ }
+ vitP->vit_error = alloperr;
+ }
+ }
+ vitP->vit_operands = count;
+ return (bug);
+}
+
+#ifdef test
+
+/*
+ * Test program for above.
+ */
+
+struct vit myvit; /* build an exploded vax instruction here */
+char answer[100]; /* human types a line of vax assembler here */
+char *mybug; /* "" or an internal logic diagnostic */
+int mycount; /* number of operands */
+struct vop *myvop; /* scan operands from myvit */
+int mysynth; /* TRUE means want synthetic opcodes. */
+char my_immediate[200];
+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 (answer);
+ sscanf (answer, "%d", &mysynth);
+ printf ("Synthetic opcodes %s be included.\n", mysynth ? "will" : "will not");
+ printf ("enter immediate symbols eg enter # ");
+ gets (my_immediate);
+ printf ("enter indirect symbols eg enter @ ");
+ gets (my_indirect);
+ printf ("enter displen symbols eg enter ^ ");
+ gets (my_displen);
+ if (*(p = vip_begin (mysynth, my_immediate, my_indirect, my_displen)))
+ {
+ error ("vip_begin=%s", p);
+ }
+ printf ("An empty input line will quit you from the vax instruction parser\n");
+ for (;;)
+ {
+ printf ("vax instruction: ");
+ fflush (stdout);
+ gets (answer);
+ if (!*answer)
+ {
+ break; /* out of for each input text loop */
+ }
+ mybug = vip (&myvit, answer);
+ if (*mybug)
+ {
+ printf ("BUG:\"%s\"\n", mybug);
+ }
+ if (*myvit.vit_error)
+ {
+ printf ("ERR:\"%s\"\n", myvit.vit_error);
+ }
+ printf ("opcode=");
+ for (mycount = myvit.vit_opcode_nbytes, p = myvit.vit_opcode;
+ mycount;
+ mycount--, p++
+ )
+ {
+ printf ("%02x ", *p & 0xFF);
+ }
+ printf (" operand count=%d.\n", mycount = myvit.vit_operands);
+ for (myvop = myvit.vit_operand; mycount; mycount--, myvop++)
+ {
+ printf ("mode=%xx reg=%xx ndx=%xx len='%c'=%c%c%d. expr=\"",
+ myvop->vop_mode, myvop->vop_reg, myvop->vop_ndx,
+ myvop->vop_short, myvop->vop_access, myvop->vop_width,
+ myvop->vop_nbytes);
+ for (p = myvop->vop_expr_begin; p <= myvop->vop_expr_end; p++)
+ {
+ putchar (*p);
+ }
+ printf ("\"\n");
+ if (*myvop->vop_error)
+ {
+ printf (" err:\"%s\"\n", myvop->vop_error);
+ }
+ if (*myvop->vop_warn)
+ {
+ printf (" wrn:\"%s\"\n", myvop->vop_warn);
+ }
+ }
+ }
+ vip_end ();
+ exit ();
+}
+
+#endif /* #ifdef test */
+
+/* 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. */
+
+/*
+ * v a x _ r e g _ p a r s e ( )
+ *
+ * Take 3 char.s, the last of which may be `\0` (non-existent)
+ * and return the VAX register number that they represent.
+ *
+ * Return -1 if they don't form a register name. Good names return
+ * a number from 0:15 inclusive.
+ *
+ * Case is not important in a name.
+ *
+ * Register names understood are:
+ *
+ * R0
+ * R1
+ * R2
+ * R3
+ * R4
+ * R5
+ * R6
+ * R7
+ * R8
+ * R9
+ * R10
+ * R11
+ * R12 AP
+ * R13 FP
+ * R14 SP
+ * R15 PC
+ *
+ */
+
+#include <ctype.h>
+#define AP (12)
+#define FP (13)
+#define SP (14)
+#define PC (15)
+
+int /* return -1 or 0:15 */
+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 */
+
+ retval = -1;
+
+ if (isupper (c1))
+ c1 = tolower (c1);
+ if (isupper (c2))
+ c2 = tolower (c2);
+ if (isdigit (c2) && c1 == 'r')
+ {
+ retval = c2 - '0';
+ if (isdigit (c3))
+ {
+ retval = retval * 10 + c3 - '0';
+ retval = (retval > 15) ? -1 : retval;
+ /* clamp the register value to 1 hex digit */
+ }
+ else if (c3)
+ retval = -1; /* c3 must be '\0' or a digit */
+ }
+ else if (c3) /* There are no three letter regs */
+ retval = -1;
+ else if (c2 == 'p')
+ {
+ switch (c1)
+ {
+ case 's':
+ retval = SP;
+ break;
+ case 'f':
+ retval = FP;
+ break;
+ case 'a':
+ retval = AP;
+ break;
+ default:
+ retval = -1;
+ }
+ }
+ else if (c1 == 'p' && c2 == 'c')
+ retval = PC;
+ else
+ retval = -1;
+ return (retval);
+}
+
+/* end: vax_reg_parse.c */
+
+ /* JF this was another separate prog */
+/* vip_op.c - parse 1 VAX instr's operand.(C)1986 Free Software Foundation. */
+
+/* JF #include <ctype.h> */
+/* #include "vax_inst.h" */
+
+/*
+ * v i p _ o p ( )
+ *
+ * Parse a vax operand in DEC assembler notation.
+ * For speed, expect a string of whitespace to be reduced to a single ' '.
+ * This is the case for GNU AS, and is easy for other DEC-compatible
+ * assemblers.
+ *
+ * Knowledge about DEC VAX assembler operand notation lives here.
+ * This doesn't even know what a register name is, except it believes
+ * all register names are 2 or 3 characters, and lets vax_reg_parse() say
+ * what number each name represents.
+ * It does, however, know that PC, SP etc are special registers so it can
+ * detect addressing modes that are silly for those registers.
+ *
+ * Where possible, it delivers 1 fatal or 1 warning message if the operand
+ * is suspect. Exactly what we test for is still evolving.
+ */
+
+/*
+ * B u g s
+ *
+ * Arg block.
+ *
+ * There were a number of 'mismatched argument type' bugs to vip_op.
+ * The most general solution is to typedef each (of many) arguments.
+ * We used instead a typedef'd argument block. This is less modular
+ * than using seperate return pointers for each result, but runs faster
+ * on most engines, and seems to keep programmers happy. It will have
+ * to be done properly if we ever want to use vip_op as a general-purpose
+ * module (it was designed to be).
+ *
+ * G^
+ *
+ * Doesn't support DEC "G^" format operands. These always take 5 bytes
+ * to express, and code as modes 8F or 9F. Reason: "G^" deprives you of
+ * optimising to (say) a "B^" if you are lucky in the way you link.
+ * When someone builds a linker smart enough to convert "G^" to "B^", "W^"
+ * whenever possible, then we should implement it.
+ * If there is some other use for "G^", feel free to code it in!
+ *
+ *
+ * speed
+ *
+ * If I nested if()s more, I could avoid testing (*err) which would save
+ * time, space and page faults. I didn't nest all those if()s for clarity
+ * and because I think the mode testing can be re-arranged 1st to test the
+ * commoner constructs 1st. Does anybody have statistics on this?
+ *
+ *
+ *
+ * error messages
+ *
+ * In future, we should be able to 'compose' error messages in a scratch area
+ * and give the user MUCH more informative error messages. Although this takes
+ * a little more code at run-time, it will make this module much more self-
+ * documenting. As an example of what sucks now: most error messages have
+ * hardwired into them the DEC VAX metacharacters "#^@" which are nothing like
+ * the Un*x characters "$`*", that most users will expect from this AS.
+ */
+
+/*
+ * The input is a string, ending with '\0'.
+ *
+ * We also require a 'hint' of what kind of operand is expected: so
+ * we can remind caller not to write into literals for instance.
+ *
+ * The output is a skeletal instruction.
+ *
+ * The algorithm has two parts.
+ * 1. extract the syntactic features (parse off all the @^#-()+[] mode crud);
+ * 2. express the @^#-()+[] as some parameters suited to further analysis.
+ *
+ * 2nd step is where we detect the googles of possible invalid combinations
+ * a human (or compiler) might write. Note that if we do a half-way
+ * decent assembler, we don't know how long to make (eg) displacement
+ * fields when we first meet them (because they may not have defined values).
+ * So we must wait until we know how many bits are needed for each address,
+ * then we can know both length and opcodes of instructions.
+ * For reason(s) above, we will pass to our caller a 'broken' instruction
+ * of these major components, from which our caller can generate instructions:
+ * - displacement length I^ S^ L^ B^ W^ unspecified
+ * - mode (many)
+ * - register R0-R15 or absent
+ * - index register R0-R15 or absent
+ * - expression text what we don't parse
+ * - error text(s) why we couldn't understand the operand
+ */
+
+/*
+ * To decode output of this, test errtxt. If errtxt[0] == '\0', then
+ * we had no errors that prevented parsing. Also, if we ever report
+ * an internal bug, errtxt[0] is set non-zero. So one test tells you
+ * if the other outputs are to be taken seriously.
+ */
+
+
+ /* vax registers we need to know */
+/* JF #define SP (14)
+/* JF for one big happy file #define PC (15) */
+
+ /* useful ideas */
+/* #define TRUE (1) */
+/* #define FALSE (0) */
+
+/*
+ * 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
+ * the different conventions for assembler operand notation. For example
+ * VMS says "#42" for immediate mode, while most UN*X say "$42".
+ * We permit arbitrary sets of (single) characters to represent the
+ * 3 concepts that DEC writes '#', '@', '^'.
+ */
+
+ /* character tests */
+#define VIP_IMMEDIATE 01 /* Character is like DEC # */
+#define VIP_INDIRECT 02 /* Char is like DEC @ */
+#define VIP_DISPLEN 04 /* Char is like DEC ^ */
+
+#define IMMEDIATEP(c) (vip_metacharacters [(c)&0xff]&VIP_IMMEDIATE)
+#define INDIRECTP(c) (vip_metacharacters [(c)&0xff]&VIP_INDIRECT)
+#define DISPLENP(c) (vip_metacharacters [(c)&0xff]&VIP_DISPLEN)
+
+/* We assume 8 bits per byte. Use vip_op_defaults() to set these up BEFORE we
+ * are ever called.
+ */
+
+#if defined(CONST_TABLE)
+#define _ 0,
+#define I VIP_IMMEDIATE,
+#define S VIP_INDIRECT,
+#define D VIP_DISPLEN,
+static const char
+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 ^[ ^\ ^] ^^ ^_*/
+_ _ _ _ I _ _ _ _ _ S _ _ _ _ _/*sp ! " # $ % & ' ( ) * + , - . /*/
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*0 1 2 3 4 5 6 7 8 9 : ; < = > ?*/
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*@ 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 [ \ ] ^ _*/
+D _ _ _ _ _ _ _ _ _ _ _ _ _ _ _/*` 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 { | } ~ ^?*/
+
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+};
+#undef _
+#undef I
+#undef S
+#undef D
+#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;
+char *syms;
+{
+ unsigned char t;
+
+ while(t= *syms++)
+ 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
+
+vip_op_defaults (immediate, indirect, displen) /* can be called any time */
+ char *immediate, /* Strings of characters for each job. */
+ *indirect, *displen; /* more arguments may appear in future! */
+{
+ vip_op_1 (VIP_IMMEDIATE, immediate);
+ vip_op_1 (VIP_INDIRECT, indirect);
+ vip_op_1 (VIP_DISPLEN, displen);
+}
+#endif
+
+
+/*
+ * Dec defines the semantics of address modes (and values)
+ * by a two-letter code, explained here.
+ *
+ * letter 1: access type
+ *
+ * a address calculation - no data access, registers forbidden
+ * b branch displacement
+ * m read - let go of bus - write back "modify"
+ * r read
+ * v bit field address: like 'a' but registers are OK
+ * w write
+ * space no operator (eg ".long foo") [our convention]
+ *
+ * letter 2: data type (i.e. width, alignment)
+ *
+ * b byte
+ * d double precision floating point (D format)
+ * f single precision floating point (F format)
+ * g G format floating
+ * h H format floating
+ * l longword
+ * o octaword
+ * q quadword
+ * w word
+ * ? simple synthetic branch operand
+ * - unconditional synthetic JSB/JSR operand
+ * ! complex synthetic branch operand
+ *
+ * The '-?!' letter 2's are not for external consumption. They are used
+ * for various assemblers. Generally, all unknown widths are assumed 0.
+ * We don't limit your choice of width character.
+ *
+ * DEC operands are hard work to parse. For example, '@' as the first
+ * character means indirect (deferred) mode but elswhere it is a shift
+ * operator.
+ * The long-winded explanation of how this is supposed to work is
+ * cancelled. Read a DEC vax manual.
+ * We try hard not to parse anything that MIGHT be part of the expression
+ * buried in that syntax. For example if we see @...(Rn) we don't check
+ * for '-' before the '(' because mode @-(Rn) does not exist.
+ *
+ * After parsing we have:
+ *
+ * at TRUE if leading '@' (or Un*x '*')
+ * len takes one value from " bilsw". eg B^ -> 'b'.
+ * hash TRUE if leading '#' (or Un*x '$')
+ * expr_begin, expr_end the expression we did not parse
+ * even though we don't interpret it, we make use
+ * of its presence or absence.
+ * sign -1: -(Rn) 0: absent +1: (Rn)+
+ * paren TRUE if () are around register
+ * reg major register number 0:15 -1 means absent
+ * ndx index register number 0:15 -1 means absent
+ *
+ * Again, I dare not explain it: just trace ALL the code!
+ */
+
+char * /* (code here) bug message, "" = OK */
+ /* our code bug, NOT bad assembly language */
+vip_op (optext, vopP)
+ char *optext; /* user's input string e.g.: */
+ /* "@B^foo@bar(AP)[FP]:" */
+ struct vop *vopP; /* In: vop_access, vop_width. */
+ /* Out: _ndx, _reg, _mode, _short, _warn, */
+ /* _error _expr_begin, _expr_end, _nbytes. */
+ /* vop_nbytes : number of bytes in a datum. */
+{
+ char *p; /* track operand text forward */
+ char *q; /* track operand text backward */
+ int at; /* TRUE if leading '@' ('*') seen */
+ char len; /* one of " bilsw" */
+ int hash; /* TRUE if leading '#' ('$') seen */
+ int sign; /* -1, 0 or +1 */
+ int paren; /* TRUE if () surround register */
+ int reg; /* register number, -1:absent */
+ int ndx; /* index register number -1:absent */
+ char *bug; /* report any logic error in here, ""==OK */
+ char *err; /* 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; /* preserve q in case we backup */
+ int mode; /* build up 4-bit operand mode here */
+ /* note: index mode is in ndx, this is */
+ /* the major mode of operand address */
+/*
+ * 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 */
+
+ p = optext;
+
+ if (*p == ' ') /* Expect all whitespace reduced to ' '. */
+ p++; /* skip over whitespace */
+
+ if (at = INDIRECTP (*p))
+ { /* TRUE if *p=='@'(or '*' for Un*x) */
+ p++; /* at is determined */
+ if (*p == ' ') /* Expect all whitespace reduced to ' '. */
+ p++; /* skip over whitespace */
+ }
+
+ /*
+ * 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;
+
+ c = *p;
+ if (isupper (c))
+ c = tolower (c);
+ if (DISPLENP (p[1]) && index ("bilws", len = c))
+ p += 2; /* skip (letter) '^' */
+ else /* no (letter) '^' seen */
+ len = ' '; /* len is determined */
+ }
+
+ if (*p == ' ') /* Expect all whitespace reduced to ' '. */
+ p++; /* skip over whitespace */
+
+ if (hash = IMMEDIATEP (*p)) /* TRUE if *p=='#' ('$' for Un*x) */
+ 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).
+ */
+
+ for (q = p; *q; q++)
+ ;
+ q--; /* now q points at last char of text */
+
+ if (*q == ' ' && q >= p) /* Expect all whitespace reduced to ' '. */
+ q--;
+ /* reverse over whitespace, but don't */
+ /* 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 ']'.
+ */
+ if (*q == ']')
+ {
+ while (q >= p && *q != '[')
+ q--;
+ /* either q<p or we got matching '[' */
+ if (q < p)
+ err = "no '[' to match ']'";
+ else
+ {
+ /*
+ * Confusers like "[]" will eventually lose with a bad register
+ * name error. So again we don't need to check for early '\0'.
+ */
+ if (q[3] == ']')
+ ndx = vax_reg_parse (q[1], q[2], 0);
+ else if (q[4] == ']')
+ ndx = vax_reg_parse (q[1], q[2], q[3]);
+ else
+ ndx = -1;
+ /*
+ * 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)
+ err = "[PC] index banned";
+ else
+ q--; /* point q just before "[...]" */
+ }
+ }
+ else
+ 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 (*q == ' ' && q >= p) /* Expect all whitespace reduced to ' '. */
+ q--;
+ /* reverse over whitespace, but don't */
+ /* run back over *p */
+ if (!*err)
+ {
+ sign = 0; /* no ()+ or -() seen yet */
+
+ if (q > p + 3 && *q == '+' && q[-1] == ')')
+ {
+ sign = 1; /* we saw a ")+" */
+ q--; /* q points to ')' */
+ }
+
+ if (*q == ')' && q > p + 2)
+ {
+ paren = TRUE; /* assume we have "(...)" */
+ while (q >= p && *q != '(')
+ q--;
+ /* either q<p or we got matching '(' */
+ if (q < p)
+ err = "no '(' to match ')'";
+ else
+ {
+ /*
+ * Confusers like "()" will eventually lose with a bad register
+ * name error. So again we don't need to check for early '\0'.
+ */
+ if (q[3] == ')')
+ reg = vax_reg_parse (q[1], q[2], 0);
+ else if (q[4] == ')')
+ reg = vax_reg_parse (q[1], q[2], q[3]);
+ else
+ reg = -1;
+ /*
+ * Since we saw a ')' we will demand a register name in the ')'.
+ * This is nasty: why can't our hypothetical assembler permit
+ * parenthesised expressions? BECAUSE I AM LAZY! That is why.
+ * Abuse luser if we didn't spy a register name.
+ */
+ if (reg < 0)
+ {
+ /* JF allow parenthasized expressions. I hope this works */
+ paren = FALSE;
+ while (*q != ')')
+ q++;
+ /* err = "unknown register in ()"; */
+ }
+ else
+ q--; /* point just before '(' of "(...)" */
+ /*
+ * If err == "..." then we lost. Run away.
+ * Otherwise if reg >= 0 then we saw (Rn).
+ */
+ }
+ /*
+ * If err == "..." then we lost.
+ * Otherwise paren==TRUE and reg = register in "()".
+ */
+ }
+ else
+ paren = FALSE;
+ /*
+ * If err == "..." then we lost.
+ * Otherwise, q points just before "(Rn)", if any.
+ * If there was a "(...)" then paren==TRUE, and reg is the register.
+ */
+
+ /*
+ * We should only seek '-' of "-(...)" if:
+ * we saw "(...)" paren == TRUE
+ * we have no errors so far ! *err
+ * we did not see '+' of "(...)+" sign < 1
+ * 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 (paren && sign < 1)/* !sign is adequate test */
+ {
+ if (*q == '-')
+ {
+ sign = -1;
+ q--;
+ }
+ }
+ /*
+ * We have back-tracked over most
+ * of the crud at the end of an operand.
+ * Unless err, we know: sign, paren. If paren, we know reg.
+ * The last case is of an expression "Rn".
+ * This is worth hunting for if !err, !paren.
+ * We wouldn't be here if err.
+ * We remember to save q, in case we didn't want "Rn" anyway.
+ */
+ if (!paren)
+ {
+ if (*q == ' ' && q >= p) /* Expect all whitespace reduced to ' '. */
+ q--;
+ /* reverse over whitespace, but don't */
+ /* run back over *p */
+ if (q > p && q < p + 3) /* room for Rn or Rnn exactly? */
+ reg = vax_reg_parse (p[0], p[1], q < p + 2 ? 0 : p[2]);
+ else
+ reg = -1; /* always comes here if no register at all */
+ /*
+ * Here with a definitive reg value.
+ */
+ if (reg >= 0)
+ {
+ oldq = q;
+ q = p - 1;
+ }
+ }
+ }
+ }
+ /*
+ * have reg. -1:absent; else 0:15
+ */
+
+ /*
+ * We have: err, at, len, hash, ndx, sign, paren, reg.
+ * Also, any remaining expression is from *p through *q inclusive.
+ * Should there be no expression, q==p-1. So expression length = q-p+1.
+ * This completes the first part: parsing the operand text.
+ */
+
+ /*
+ * We now want to boil the data down, checking consistency on the way.
+ * We want: len, mode, reg, ndx, err, p, q, wrn, bug.
+ * We will deliver a 4-bit reg, and a 4-bit mode.
+ */
+
+ /*
+ * Case of branch operand. Different. No L^B^W^I^S^ allowed for instance.
+ *
+ * in: at ?
+ * len ?
+ * hash ?
+ * p:q ?
+ * sign ?
+ * paren ?
+ * reg ?
+ * ndx ?
+ *
+ * out: mode 0
+ * reg -1
+ * len ' '
+ * p:q whatever was input
+ * ndx -1
+ * err " " or error message, and other outputs trashed
+ */
+ /* branch operands have restricted forms */
+ if (!*err && access == 'b')
+ {
+ if (at || hash || sign || paren || ndx >= 0 || reg >= 0 || len != ' ')
+ err = "invalid branch operand";
+ else
+ err = " ";
+ }
+
+/* Since nobody seems to use it: comment this 'feature'(?) out for now. */
+#ifdef NEVER
+ /*
+ * Case of stand-alone operand. e.g. ".long foo"
+ *
+ * in: at ?
+ * len ?
+ * hash ?
+ * p:q ?
+ * sign ?
+ * paren ?
+ * reg ?
+ * ndx ?
+ *
+ * out: mode 0
+ * reg -1
+ * len ' '
+ * p:q whatever was input
+ * ndx -1
+ * err " " or error message, and other outputs trashed
+ */
+ if (!*err)
+ {
+ if (access == ' ')
+ { /* addresses have restricted forms */
+ if (at)
+ 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;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif /*#Ifdef NEVER*/
+
+ /*
+ * Case of S^#.
+ *
+ * in: at FALSE
+ * len 's' definition
+ * hash TRUE demand
+ * p:q demand not empty
+ * sign 0 by paren==FALSE
+ * paren FALSE by "()" scan logic because "S^" seen
+ * reg -1 or nn by mistake
+ * ndx -1
+ *
+ * out: mode 0
+ * reg -1
+ * len 's'
+ * exp
+ * ndx -1
+ */
+ if (!*err && len == 's')
+ {
+ if (!hash || paren || at || ndx >= 0)
+ err = "invalid operand of S^#";
+ else
+ {
+ if (reg >= 0)
+ {
+ /*
+ * SHIT! we saw S^#Rnn ! put the Rnn back in
+ * expression. KLUDGE! Use oldq so we don't
+ * need to know exact length of reg name.
+ */
+ q = oldq;
+ reg = 0;
+ }
+ /*
+ * We have all the expression we will ever get.
+ */
+ if (p > q)
+ err = "S^# needs expression";
+ else if (access == 'r')
+ {
+ err = " "; /* WIN! */
+ mode = 0;
+ }
+ else
+ err = "S^# may only read-access";
+ }
+ }
+
+ /*
+ * Case of -(Rn), which is weird case.
+ *
+ * in: at FALSE
+ * len '
+ * hash FALSE
+ * p:q q<p
+ * sign -1 by definition
+ * paren TRUE by definition
+ * reg present by definition
+ * ndx optional
+ *
+ * out: mode 7
+ * reg present
+ * len ' '
+ * exp "" enforce empty expression
+ * ndx optional warn if same as reg
+ */
+ if (!*err && sign < 0)
+ {
+ if (len != ' ' || hash || at || p <= q)
+ err = "invalid operand of -()";
+ else
+ {
+ err = " "; /* win */
+ mode = 7;
+ if (reg == PC)
+ wrn = "-(PC) unpredictable";
+ else if (reg == ndx)
+ wrn = "[]index same as -()register: unpredictable";
+ }
+ }
+
+ /*
+ * We convert "(Rn)" to "@Rn" for our convenience.
+ * (I hope this is convenient: has someone got a better way to parse this?)
+ * A side-effect of this is that "@Rn" is a valid operand.
+ */
+ if (paren && !sign && !hash && !at && len == ' ' && p > q)
+ {
+ at = TRUE;
+ paren = FALSE;
+ }
+
+ /*
+ * Case of (Rn)+, which is slightly different.
+ *
+ * in: at
+ * len ' '
+ * hash FALSE
+ * p:q q<p
+ * sign +1 by definition
+ * paren TRUE by definition
+ * reg present by definition
+ * ndx optional
+ *
+ * out: mode 8+@
+ * reg present
+ * len ' '
+ * exp "" enforce empty expression
+ * ndx optional warn if same as reg
+ */
+ if (!*err && sign > 0)
+ {
+ if (len != ' ' || hash || p <= q)
+ err = "invalid operand of ()+";
+ else
+ {
+ err = " "; /* win */
+ mode = 8 + (at ? 1 : 0);
+ if (reg == PC)
+ wrn = "(PC)+ unpredictable";
+ else if (reg == ndx)
+ wrn = "[]index same as ()+register: unpredictable";
+ }
+ }
+
+ /*
+ * Case of #, without S^.
+ *
+ * in: at
+ * len ' ' or 'i'
+ * hash TRUE by definition
+ * p:q
+ * sign 0
+ * paren FALSE
+ * reg absent
+ * ndx optional
+ *
+ * out: mode 8+@
+ * reg PC
+ * len ' ' or 'i'
+ * exp
+ * ndx optional
+ */
+ if (!*err && hash)
+ {
+ if (len != 'i' && len != ' ')
+ err = "# conflicts length";
+ else if (paren)
+ err = "# bars register";
+ else
+ {
+ if (reg >= 0)
+ {
+ /*
+ * SHIT! we saw #Rnn! Put the Rnn back into the expression.
+ * By using oldq, we don't need to know how long Rnn was.
+ * KLUDGE!
+ */
+ q = oldq;
+ reg = -1; /* no register any more */
+ }
+ err = " "; /* win */
+
+ /* JF a bugfix, I think! */
+ if(at && access=='a')
+ vopP->vop_nbytes=4;
+
+ mode = (at ? 9 : 8);
+ reg = PC;
+ if ((access == 'm' || access == 'w') && !at)
+ wrn = "writing or modifying # is unpredictable";
+ }
+ }
+ /*
+ * If !*err, then sign == 0
+ * hash == FALSE
+ */
+
+ /*
+ * Case of Rn. We seperate this one because it has a few special
+ * errors the remaining modes lack.
+ *
+ * in: at optional
+ * len ' '
+ * hash FALSE by program logic
+ * p:q empty
+ * sign 0 by program logic
+ * paren FALSE by definition
+ * reg present by definition
+ * ndx optional
+ *
+ * out: mode 5+@
+ * reg present
+ * len ' ' enforce no length
+ * exp "" enforce empty expression
+ * ndx optional warn if same as reg
+ */
+ if (!*err && !paren && reg >= 0)
+ {
+ if (len != ' ')
+ err = "length not needed";
+ else if (at)
+ {
+ err = " "; /* win */
+ mode = 6; /* @Rn */
+ }
+ else if (ndx >= 0)
+ err = "can't []index a register, because it has no address";
+ else if (access == 'a')
+ err = "a register has no address";
+ else
+ {
+ /*
+ * Idea here is to detect from length of datum
+ * and from register number if we will touch PC.
+ * Warn if we do.
+ * vop_nbytes is number of bytes in operand.
+ * Compute highest byte affected, compare to PC0.
+ */
+ if ((vopP->vop_nbytes + reg * 4) > 60)
+ wrn = "PC part of operand unpredictable";
+ err = " "; /* win */
+ mode = 5; /* Rn */
+ }
+ }
+ /*
+ * If !*err, sign == 0
+ * hash == FALSE
+ * paren == TRUE OR reg==-1
+ */
+
+ /*
+ * Rest of cases fit into one bunch.
+ *
+ * in: at optional
+ * len ' ' or 'b' or 'w' or 'l'
+ * hash FALSE 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 = " "; /* win (always) */
+ mode = 10 + (at ? 1 : 0);
+ switch (len)
+ {
+ case 'l':
+ mode += 2;
+ case 'w':
+ mode += 2;
+ case ' ': /* assumed B^ until our caller changes it */
+ case 'b':
+ break;
+ }
+ }
+
+ /*
+ * here with completely specified mode
+ * len
+ * reg
+ * expression p,q
+ * ndx
+ */
+
+ if (*err == ' ')
+ err = ""; /* " " is no longer an error */
+
+ vopP->vop_mode = mode;
+ vopP->vop_reg = reg;
+ vopP->vop_short = len;
+ vopP->vop_expr_begin = p;
+ vopP->vop_expr_end = q;
+ vopP->vop_ndx = ndx;
+ vopP->vop_error = err;
+ vopP->vop_warn = wrn;
+ return (bug);
+
+} /* vip_op() */
+
+/*
+
+Summary of vip_op outputs.
+
+ mode reg len ndx
+(Rn) => @Rn
+{@}Rn 5+@ n ' ' optional
+branch operand 0 -1 ' ' -1
+S^#foo 0 -1 's' -1
+-(Rn) 7 n ' ' optional
+{@}(Rn)+ 8+@ n ' ' optional
+{@}#foo, no S^ 8+@ PC " i" optional
+{@}{q^}{(Rn)} 10+@+q option " bwl" optional
+
+*/
+
+#ifdef TEST /* #Define to use this testbed. */
+
+/*
+ * Follows a test program for this function.
+ * We declare arrays non-local in case some of our tiny-minded machines
+ * default to small stacks. Also, helps with some debuggers.
+ */
+
+#include <stdio.h>
+
+char answer[100]; /* human types into here */
+char *p; /* */
+char *myerr;
+char *mywrn;
+char *mybug;
+char myaccess;
+char mywidth;
+char mymode;
+char myreg;
+char mylen;
+char *myleft;
+char *myright;
+char myndx;
+int my_operand_length;
+char my_immediate[200];
+char my_indirect[200];
+char my_displen[200];
+
+main ()
+{
+ char *vip_op (); /* make cc happy */
+
+ printf ("enter immediate symbols eg enter # ");
+ gets (my_immediate);
+ printf ("enter indirect symbols eg enter @ ");
+ gets (my_indirect);
+ printf ("enter displen symbols eg enter ^ ");
+ gets (my_displen);
+ vip_op_defaults (my_immediate, my_indirect, my_displen);
+ for (;;)
+ {
+ printf ("access,width (eg 'ab' or 'wh') [empty line to quit] : ");
+ fflush (stdout);
+ gets (answer);
+ if (!answer[0])
+ exit (0);
+ myaccess = answer[0];
+ mywidth = answer[1];
+ switch (mywidth)
+ {
+ case 'b':
+ my_operand_length = 1;
+ break;
+ case 'd':
+ my_operand_length = 8;
+ break;
+ case 'f':
+ my_operand_length = 4;
+ break;
+ case 'g':
+ my_operand_length = 16;
+ break;
+ case 'h':
+ my_operand_length = 32;
+ break;
+ case 'l':
+ my_operand_length = 4;
+ break;
+ case 'o':
+ my_operand_length = 16;
+ break;
+ case 'q':
+ my_operand_length = 8;
+ break;
+ case 'w':
+ my_operand_length = 2;
+ break;
+ case '!':
+ case '?':
+ case '-':
+ my_operand_length = 0;
+ break;
+
+ default:
+ my_operand_length = 2;
+ printf ("I dn't understand access width %c\n", mywidth);
+ break;
+ }
+ printf ("VAX assembler instruction operand: ");
+ fflush (stdout);
+ gets (answer);
+ mybug = vip_op (answer, myaccess, mywidth, my_operand_length,
+ &mymode, &myreg, &mylen, &myleft, &myright, &myndx,
+ &myerr, &mywrn);
+ if (*myerr)
+ {
+ printf ("error: \"%s\"\n", myerr);
+ if (*mybug)
+ printf (" bug: \"%s\"\n", mybug);
+ }
+ else
+ {
+ if (*mywrn)
+ printf ("warning: \"%s\"\n", mywrn);
+ mumble ("mode", mymode);
+ mumble ("register", myreg);
+ mumble ("index", myndx);
+ printf ("width:'%c' ", mylen);
+ printf ("expression: \"");
+ while (myleft <= myright)
+ putchar (*myleft++);
+ printf ("\"\n");
+ }
+ }
+}
+
+mumble (text, value)
+ char *text;
+ int value;
+{
+ printf ("%s:", text);
+ if (value >= 0)
+ printf ("%xx", value);
+ else
+ printf ("ABSENT");
+ printf (" ");
+}
+
+#endif /* ifdef TEST */
+
+/* end: vip_op.c */
+
+/* end: vax.c */
+
+/* JF: new routines */
+
+const int md_short_jump_size = 3;
+
+const int md_long_jump_size = 6;
+
+void
+md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ long from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ long offset;
+
+ offset = to_addr - (from_addr + 1);
+ *ptr++ = 0x31;
+ md_number_to_chars (ptr, offset, 2);
+}
+
+void
+md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ long from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ long offset;
+
+ offset = to_addr - to_symbol->sy_value;
+ *ptr++ = 0x17;
+ *ptr++ = 0x9F;
+ md_number_to_chars (ptr, offset, 4);
+ fix_new (frag, ptr - frag->fr_literal, 4, to_symbol, (symbolS *) 0, (long int) 0, 0);
+}
+
+int
+md_parse_option (argP, cntP, vecP)
+ char **argP;
+ int *cntP;
+ char ***vecP;
+{
+ char *temp_name; /* name for -t or -d options */
+ char opt;
+
+ switch (**argP)
+ {
+ case 'J':
+ /* as_warn ("I can do better than -J!"); */
+ break;
+
+ case 'S':
+ as_warn ("SYMBOL TABLE not implemented");
+ break; /* SYMBOL TABLE not implemented */
+
+ case 'T':
+ as_warn ("TOKEN TRACE not implemented");
+ break; /* TOKEN TRACE not implemented */
+
+ 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);
+ break;
+
+ case 'V':
+ as_warn ("I don't use an interpass file! -V ignored");
+ break;
+
+#ifdef VMS
+ case '+': /* For g++ */
+ break;
+
+ case 'h': /* No hashing of mixed-case names */
+ break;
+
+ case 'H': /* Show new symbol after hash truncation */
+ break;
+#endif
+
+ default:
+ return 0;
+
+ }
+ return 1;
+}