aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/atof-vax.c348
-rw-r--r--gas/config/tc-pdp11.c798
-rw-r--r--gas/config/tc-tic30.c2257
-rw-r--r--gas/config/tc-tic30.h22
5 files changed, 1639 insertions, 1793 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index ec121e1..ad73b79 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,10 @@
+2005-03-23 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-tic30.c: Convert to ISO C90 formatting.
+ * config/tc-tic30.h: Convert to ISO C90 formatting.
+ * config/tc-pdp11.c: Convert to ISO C90 formatting.
+ * config/atof-vax.c: Convert to ISO C90 formatting.
+
2005-03-21 Maciej W. Rozycki <macro@mips.com>
* config/tc-mips.c (mips_frob_file): Sort BFD_RELOC_MIPS16_LO16
diff --git a/gas/config/atof-vax.c b/gas/config/atof-vax.c
index 7c9f04e..b94e560 100644
--- a/gas/config/atof-vax.c
+++ b/gas/config/atof-vax.c
@@ -1,5 +1,5 @@
/* atof_vax.c - turn a Flonum into a VAX floating point number
- Copyright 1987, 1992, 1993, 1995, 1997, 1999, 2000
+ Copyright 1987, 1992, 1993, 1995, 1997, 1999, 2000, 2005
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -21,37 +21,28 @@
#include "as.h"
-static int atof_vax_sizeof PARAMS ((int));
-static int next_bits PARAMS ((int));
-static void make_invalid_floating_point_number PARAMS ((LITTLENUM_TYPE *));
-static int what_kind_of_float PARAMS ((int, int *, long *));
-static char *atof_vax PARAMS ((char *, int, LITTLENUM_TYPE *));
-
/* Precision in LittleNums. */
-#define MAX_PRECISION (8)
-#define H_PRECISION (8)
-#define G_PRECISION (4)
-#define D_PRECISION (4)
-#define F_PRECISION (2)
+#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)
+#define GUARD 2
-int flonum_gen2vax PARAMS ((int format_letter, FLONUM_TYPE * f,
- LITTLENUM_TYPE * words));
+int flonum_gen2vax (int, FLONUM_TYPE *, LITTLENUM_TYPE *);
/* Number of chars in flonum type 'letter'. */
+
static int
-atof_vax_sizeof (letter)
- int letter;
+atof_vax_sizeof (int 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!
- */
+ /* 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':
@@ -75,8 +66,9 @@ atof_vax_sizeof (letter)
return_value = 0;
break;
}
- return (return_value);
-} /* atof_vax_sizeof */
+
+ return return_value;
+}
static const long mask[] =
{
@@ -116,14 +108,13 @@ static const long mask[] =
};
-/* Shared between flonum_gen2vax and next_bits */
+/* 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;
+next_bits (int number_of_bits)
{
int return_value;
@@ -144,23 +135,22 @@ next_bits (number_of_bits)
bits_left_in_littlenum -= number_of_bits;
return_value = mask[number_of_bits] & ((*littlenum_pointer) >> bits_left_in_littlenum);
}
- return (return_value);
+ return return_value;
}
static void
-make_invalid_floating_point_number (words)
- LITTLENUM_TYPE *words;
+make_invalid_floating_point_number (LITTLENUM_TYPE *words)
{
- *words = 0x8000; /* Floating Reserved Operand Code */
+ *words = 0x8000; /* Floating Reserved Operand Code. */
}
+
static int /* 0 means letter is OK. */
-what_kind_of_float (letter, precisionP, exponent_bitsP)
- int letter; /* In: lowercase please. What kind of float? */
- int *precisionP; /* Number of 16-bit words in the float. */
- long *exponent_bitsP; /* Number of exponent bits. */
+what_kind_of_float (int letter, /* In: lowercase please. What kind of float? */
+ int *precisionP, /* Number of 16-bit words in the float. */
+ long *exponent_bitsP) /* Number of exponent bits. */
{
- int retval; /* 0: OK. */
+ int retval;
retval = 0;
switch (letter)
@@ -189,29 +179,24 @@ what_kind_of_float (letter, precisionP, exponent_bitsP)
retval = 69;
break;
}
- return (retval);
+ 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! *
- * *
- \***********************************************************************/
-
-static char * /* Return pointer past text consumed. */
-atof_vax (str, what_kind, words)
- char *str; /* Text to convert to binary. */
- int what_kind; /* 'd', 'f', 'g', 'h' */
- LITTLENUM_TYPE *words; /* Build the binary here. */
+/* 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! */
+
+static char *
+atof_vax (char *str, /* Text to convert to binary. */
+ int 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. */
+ /* 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 exponent_bits;
@@ -225,7 +210,7 @@ atof_vax (str, what_kind, words)
if (what_kind_of_float (what_kind, &precision, &exponent_bits))
{
- return_value = NULL; /* We lost. */
+ return_value = NULL;
make_invalid_floating_point_number (words);
}
@@ -233,37 +218,30 @@ atof_vax (str, what_kind, words)
{
memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
- /* Use more LittleNums than seems */
- /* necessary: the highest flonum may have */
- /* 15 leading 0 bits, so could be useless. */
+ /* 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_value = NULL;
}
+ else if (flonum_gen2vax (what_kind, &f, words))
+ return_value = NULL;
}
- return (return_value);
-} /* atof_vax() */
+
+ 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)
- int format_letter; /* One of 'd' 'f' 'g' 'h'. */
- FLONUM_TYPE *f;
- LITTLENUM_TYPE *words; /* Deliver answer here. */
+/* In: a flonum, a vax floating point format.
+ Out: a vax floating-point bit pattern. */
+
+int
+flonum_gen2vax (int format_letter, /* One of 'd' 'f' 'g' 'h'. */
+ FLONUM_TYPE *f,
+ LITTLENUM_TYPE *words) /* Deliver answer here. */
{
LITTLENUM_TYPE *lp;
int precision;
@@ -273,16 +251,14 @@ flonum_gen2vax (format_letter, f, words)
return_value = what_kind_of_float (format_letter, &precision, &exponent_bits);
if (return_value != 0)
- {
- make_invalid_floating_point_number (words);
- }
+ make_invalid_floating_point_number (words);
+
else
{
if (f->low > f->leader)
- {
- /* 0.0e0 seen. */
- memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision);
- }
+ /* 0.0e0 seen. */
+ memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision);
+
else
{
long exponent_1;
@@ -292,49 +268,31 @@ flonum_gen2vax (format_letter, f, words)
int exponent_skippage;
LITTLENUM_TYPE word1;
- /* JF: Deal with new Nan, +Inf and -Inf codes */
+ /* 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
+
+ /* 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. */
bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
littlenum_pointer = f->leader;
littlenum_end = f->low;
- /* Seek (and forget) 1st significant bit */
+ /* Seek (and forget) 1st significant bit. */
for (exponent_skippage = 0;
!next_bits (1);
exponent_skippage++);;
@@ -350,24 +308,19 @@ flonum_gen2vax (format_letter, f, words)
if (exponent_4 & ~mask[exponent_bits])
{
- /*
- * Exponent overflow. Lose immediately.
- */
-
+ /* 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.
- */
+ /* 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. */
+ /* 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));
@@ -375,32 +328,26 @@ flonum_gen2vax (format_letter, f, words)
/* The rest of the words are just mantissa bits. */
for (; lp < words + precision; lp++)
- {
- *lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
- }
+ *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?
- */
-
+ /* 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 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
- */
+ #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--)
@@ -413,68 +360,61 @@ flonum_gen2vax (format_letter, f, words)
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.
- */
+ /* 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);
-} /* flonum_gen2vax() */
-
-/* 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 0.
- * Floating point literal.
- * Number of chars we used for the literal.
- */
-
-#define MAXIMUM_NUMBER_OF_LITTLENUMS (8) /* For .hfloats. */
+ }
+ }
+ }
+ }
+ return return_value;
+}
+
+/* JF this used to be in vax.c but this looks like a better place for it. */
+
+/* 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 0.
+ Floating point literal.
+ Number of chars we used for the literal. */
+
+#define MAXIMUM_NUMBER_OF_LITTLENUMS 8 /* For .hfloats. */
char *
-md_atof (what_statement_type, literalP, sizeP)
- int what_statement_type;
- char *literalP;
- int *sizeP;
+md_atof (int 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 *littlenumP;
+ char kind_of_float;
+ int number_of_chars;
+ LITTLENUM_TYPE *littlenumP;
switch (what_statement_type)
{
- case 'F': /* .float */
- case 'f': /* .ffloat */
+ case 'F':
+ case 'f':
kind_of_float = 'f';
break;
- case 'D': /* .double */
- case 'd': /* .dfloat */
+ case 'D':
+ case 'd':
kind_of_float = 'd';
break;
- case 'g': /* .gfloat */
+ case 'g':
kind_of_float = 'g';
break;
- case 'h': /* .hfloat */
+ case 'h':
kind_of_float = 'h';
break;
@@ -485,17 +425,15 @@ md_atof (what_statement_type, literalP, sizeP)
if (kind_of_float)
{
- register LITTLENUM_TYPE *limit;
+ LITTLENUM_TYPE *limit;
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.
- */
+ /* 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));
@@ -506,12 +444,8 @@ md_atof (what_statement_type, literalP, sizeP)
};
}
else
- {
- number_of_chars = 0;
- };
+ number_of_chars = 0;
*sizeP = number_of_chars;
return kind_of_float ? NULL : _("Bad call to md_atof()");
}
-
-/* end of atof-vax.c */
diff --git a/gas/config/tc-pdp11.c b/gas/config/tc-pdp11.c
index 71870bd..19311e6 100644
--- a/gas/config/tc-pdp11.c
+++ b/gas/config/tc-pdp11.c
@@ -17,37 +17,22 @@
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/*
- Apparently unused functions:
- md_convert_frag
- md_estimate_size_before_relax
- md_create_short_jump
- md_create_long_jump
-*/
-
#include "as.h"
#include "safe-ctype.h"
#include "opcode/pdp11.h"
-static int set_option PARAMS ((char *arg));
-static int set_cpu_model PARAMS ((char *arg));
-static int set_machine_model PARAMS ((char *arg));
-
-extern int flonum_gen2vax PARAMS ((char format_letter, FLONUM_TYPE * f,
- LITTLENUM_TYPE * words));
+extern int flonum_gen2vax (int, FLONUM_TYPE * f, LITTLENUM_TYPE *);
-#define TRUE 1
+#define TRUE 1
#define FALSE 0
-/*
- * A representation for PDP-11 machine code.
- */
+/* A representation for PDP-11 machine code. */
struct pdp11_code
{
char *error;
int code;
- int additional; /* is there an additional word? */
- int word; /* additional word, if any */
+ int additional; /* Is there an additional word? */
+ int word; /* Additional word, if any. */
struct
{
bfd_reloc_code_real_type type;
@@ -56,17 +41,13 @@ struct pdp11_code
} reloc;
};
-/*
- * Instruction set extensions.
- *
- * If you change this from an array to something else, please update
- * the "PDP-11 instruction set extensions" comment in pdp11.h.
- */
+/* Instruction set extensions.
+
+ If you change this from an array to something else, please update
+ the "PDP-11 instruction set extensions" comment in pdp11.h. */
int pdp11_extension[PDP11_EXT_NUM];
-/*
- * Assembly options.
- */
+/* Assembly options. */
#define ASM_OPT_PIC 1
#define ASM_OPT_NUM 2
@@ -74,7 +55,7 @@ int pdp11_extension[PDP11_EXT_NUM];
int asm_option[ASM_OPT_NUM];
/* These chars start a comment anywhere in a source file (except inside
- another comment */
+ another comment. */
const char comment_chars[] = "#/";
/* These chars only start a comment at the beginning of a line. */
@@ -82,12 +63,12 @@ const char line_comment_chars[] = "#/";
const char line_separator_chars[] = ";";
-/* Chars that can be used to separate mant from exp in floating point nums */
+/* 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) */
+/* 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[] = "dDfF";
void pseudo_even (int);
@@ -100,8 +81,94 @@ const pseudo_typeS md_pseudo_table[] =
{ 0, 0, 0 },
};
+static struct hash_control *insn_hash = NULL;
+
+static int
+set_option (char *arg)
+{
+ int yes = 1;
+
+ if (strcmp (arg, "all-extensions") == 0
+ || strcmp (arg, "all") == 0)
+ {
+ memset (pdp11_extension, ~0, sizeof pdp11_extension);
+ pdp11_extension[PDP11_NONE] = 0;
+ return 1;
+ }
+ else if (strcmp (arg, "no-extensions") == 0)
+ {
+ memset (pdp11_extension, 0, sizeof pdp11_extension);
+ pdp11_extension[PDP11_BASIC] = 1;
+ return 1;
+ }
+
+ if (strncmp (arg, "no-", 3) == 0)
+ {
+ yes = 0;
+ arg += 3;
+ }
+
+ /* Commersial instructions. */
+ if (strcmp (arg, "cis") == 0)
+ pdp11_extension[PDP11_CIS] = yes;
+ /* Call supervisor mode. */
+ else if (strcmp (arg, "csm") == 0)
+ pdp11_extension[PDP11_CSM] = yes;
+ /* Extended instruction set. */
+ else if (strcmp (arg, "eis") == 0)
+ pdp11_extension[PDP11_EIS] = pdp11_extension[PDP11_LEIS] = yes;
+ /* KEV11 floating-point. */
+ else if (strcmp (arg, "fis") == 0
+ || strcmp (arg, "kev11") == 0
+ || strcmp (arg, "kev-11") == 0)
+ pdp11_extension[PDP11_FIS] = yes;
+ /* FP-11 floating-point. */
+ else if (strcmp (arg, "fpp") == 0
+ || strcmp (arg, "fpu") == 0
+ || strcmp (arg, "fp11") == 0
+ || strcmp (arg, "fp-11") == 0
+ || strcmp (arg, "fpj11") == 0
+ || strcmp (arg, "fp-j11") == 0
+ || strcmp (arg, "fpj-11") == 0)
+ pdp11_extension[PDP11_FPP] = yes;
+ /* Limited extended insns. */
+ else if (strcmp (arg, "limited-eis") == 0)
+ {
+ pdp11_extension[PDP11_LEIS] = yes;
+ if (!pdp11_extension[PDP11_LEIS])
+ pdp11_extension[PDP11_EIS] = 0;
+ }
+ /* Move from processor type. */
+ else if (strcmp (arg, "mfpt") == 0)
+ pdp11_extension[PDP11_MFPT] = yes;
+ /* Multiprocessor insns: */
+ else if (strncmp (arg, "mproc", 5) == 0
+ /* TSTSET, WRTLCK */
+ || strncmp (arg, "multiproc", 9) == 0)
+ pdp11_extension[PDP11_MPROC] = yes;
+ /* Move from/to proc status. */
+ else if (strcmp (arg, "mxps") == 0)
+ pdp11_extension[PDP11_MXPS] = yes;
+ /* Position-independent code. */
+ else if (strcmp (arg, "pic") == 0)
+ asm_option[ASM_OPT_PIC] = yes;
+ /* Set priority level. */
+ else if (strcmp (arg, "spl") == 0)
+ pdp11_extension[PDP11_SPL] = yes;
+ /* Microcode instructions: */
+ else if (strcmp (arg, "ucode") == 0
+ /* LDUB, MED, XFC */
+ || strcmp (arg, "microcode") == 0)
+ pdp11_extension[PDP11_UCODE] = yes;
+ else
+ return 0;
+
+ return 1;
+}
+
+
static void
-init_defaults ()
+init_defaults (void)
{
static int first = 1;
@@ -113,10 +180,8 @@ init_defaults ()
}
}
-static struct hash_control *insn_hash = NULL;
-
void
-md_begin ()
+md_begin (void)
{
int i;
@@ -127,21 +192,17 @@ md_begin ()
as_fatal ("Virtual memory exhausted");
for (i = 0; i < pdp11_num_opcodes; i++)
- hash_insert (insn_hash, pdp11_opcodes[i].name, (PTR)(pdp11_opcodes + i));
+ hash_insert (insn_hash, pdp11_opcodes[i].name, (void *) (pdp11_opcodes + i));
for (i = 0; i < pdp11_num_aliases; i++)
- hash_insert (insn_hash, pdp11_aliases[i].name, (PTR)(pdp11_aliases + i));
+ hash_insert (insn_hash, pdp11_aliases[i].name, (void *) (pdp11_aliases + i));
}
void
-md_number_to_chars (con, value, nbytes)
- char con[];
- valueT value;
- int nbytes;
+md_number_to_chars (char con[], valueT value, int nbytes)
{
/* On a PDP-11, 0x1234 is stored as "\x12\x34", and
- * 0x12345678 is stored as "\x56\x78\x12\x34". It's
- * anyones guess what 0x123456 would be stored like.
- */
+ 0x12345678 is stored as "\x56\x78\x12\x34". It's
+ anyones guess what 0x123456 would be stored like. */
switch (nbytes)
{
@@ -151,13 +212,13 @@ md_number_to_chars (con, value, nbytes)
con[0] = value & 0xff;
break;
case 2:
- con[0] = value & 0xff;
+ con[0] = value & 0xff;
con[1] = (value >> 8) & 0xff;
break;
case 4:
con[0] = (value >> 16) & 0xff;
con[1] = (value >> 24) & 0xff;
- con[2] = value & 0xff;
+ con[2] = value & 0xff;
con[3] = (value >> 8) & 0xff;
break;
default:
@@ -169,10 +230,9 @@ md_number_to_chars (con, value, nbytes)
that they reference. Knows about order of bytes in address. */
void
-md_apply_fix3 (fixP, valP, seg)
- fixS *fixP;
- valueT * valP;
- segT seg ATTRIBUTE_UNUSED;
+md_apply_fix3 (fixS *fixP,
+ valueT * valP,
+ segT seg ATTRIBUTE_UNUSED)
{
valueT code;
valueT mask;
@@ -223,10 +283,8 @@ md_chars_to_number (con, nbytes)
int nbytes; /* Number of bytes in the input. */
{
/* On a PDP-11, 0x1234 is stored as "\x12\x34", and
- * 0x12345678 is stored as "\x56\x78\x12\x34". It's
- * anyones guess what 0x123456 would be stored like.
- */
-
+ 0x12345678 is stored as "\x56\x78\x12\x34". It's
+ anyones guess what 0x123456 would be stored like. */
switch (nbytes)
{
case 0:
@@ -237,8 +295,8 @@ md_chars_to_number (con, nbytes)
return (con[1] << BITS_PER_CHAR) | con[0];
case 4:
return
- (((con[1] << BITS_PER_CHAR) | con[0]) << (2 * BITS_PER_CHAR)) |
- ((con[3] << BITS_PER_CHAR) | con[2]);
+ (((con[1] << BITS_PER_CHAR) | con[0]) << (2 * BITS_PER_CHAR))
+ |((con[3] << BITS_PER_CHAR) | con[2]);
default:
BAD_CASE (nbytes);
return 0;
@@ -280,14 +338,14 @@ parse_reg (char *str, struct pdp11_code *operand)
return str - 1;
}
}
- else if (strncmp (str, "sp", 2) == 0 ||
- strncmp (str, "SP", 2) == 0)
+ else if (strncmp (str, "sp", 2) == 0
+ || strncmp (str, "SP", 2) == 0)
{
operand->code = 6;
str += 2;
}
- else if (strncmp (str, "pc", 2) == 0 ||
- strncmp (str, "PC", 2) == 0)
+ else if (strncmp (str, "pc", 2) == 0
+ || strncmp (str, "PC", 2) == 0)
{
operand->code = 7;
str += 2;
@@ -305,10 +363,10 @@ static char *
parse_ac5 (char *str, struct pdp11_code *operand)
{
str = skip_whitespace (str);
- if (strncmp (str, "fr", 2) == 0 ||
- strncmp (str, "FR", 2) == 0 ||
- strncmp (str, "ac", 2) == 0 ||
- strncmp (str, "AC", 2) == 0)
+ if (strncmp (str, "fr", 2) == 0
+ || strncmp (str, "FR", 2) == 0
+ || strncmp (str, "ac", 2) == 0
+ || strncmp (str, "AC", 2) == 0)
{
str += 2;
switch (*str)
@@ -400,7 +458,8 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
}
break;
- case '#': /* immediate */
+ /* Immediate. */
+ case '#':
case '$':
str = parse_expression (str + 1, operand);
if (operand->error)
@@ -423,7 +482,7 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
operand->error = "Error in expression";
break;
}
- /* it's a floating literal... */
+ /* It's a floating literal... */
know (operand->reloc.exp.X_add_number < 0);
flonum_gen2vax ('f', &generic_floating_point_number, literal_float);
operand->word = literal_float[0];
@@ -437,7 +496,8 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
operand->code = 027;
break;
- default: /* label, d(rn), -(rn) */
+ /* label, d(rn), -(rn) */
+ default:
{
char *old = str;
@@ -463,7 +523,7 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
str = skip_whitespace (str);
- if (*str != '(') /* label */
+ if (*str != '(')
{
if (operand->reloc.exp.X_op != O_symbol)
{
@@ -478,7 +538,8 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
break;
}
- str++; /* d(rn) */
+ /* d(rn) */
+ str++;
str = parse_reg (str, operand);
if (operand->error)
return str;
@@ -507,9 +568,8 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
operand->word = operand->reloc.exp.X_add_number;
}
else
- {
- operand->word = operand->reloc.exp.X_add_number;
- }
+ operand->word = operand->reloc.exp.X_add_number;
+
break;
default:
BAD_CASE (operand->reloc.exp.X_op);
@@ -591,8 +651,7 @@ parse_separator (char *str, int *error)
}
void
-md_assemble (instruction_string)
- char *instruction_string;
+md_assemble (char *instruction_string)
{
const struct pdp11_opcode *op;
struct pdp11_code insn, op1, op2;
@@ -957,18 +1016,16 @@ md_assemble (instruction_string)
}
int
-md_estimate_size_before_relax (fragP, segment)
- fragS *fragP ATTRIBUTE_UNUSED;
- segT segment ATTRIBUTE_UNUSED;
+md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
+ segT segment ATTRIBUTE_UNUSED)
{
return 0;
}
void
-md_convert_frag (headers, seg, fragP)
- bfd *headers ATTRIBUTE_UNUSED;
- segT seg ATTRIBUTE_UNUSED;
- fragS *fragP ATTRIBUTE_UNUSED;
+md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
+ segT seg ATTRIBUTE_UNUSED,
+ fragS *fragP ATTRIBUTE_UNUSED)
{
}
@@ -976,98 +1033,25 @@ int md_short_jump_size = 2;
int md_long_jump_size = 4;
void
-md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
- char *ptr ATTRIBUTE_UNUSED;
- addressT from_addr ATTRIBUTE_UNUSED;
- addressT to_addr ATTRIBUTE_UNUSED;
- fragS *frag ATTRIBUTE_UNUSED;
- symbolS *to_symbol ATTRIBUTE_UNUSED;
+md_create_short_jump (char *ptr ATTRIBUTE_UNUSED,
+ addressT from_addr ATTRIBUTE_UNUSED,
+ addressT to_addr ATTRIBUTE_UNUSED,
+ fragS *frag ATTRIBUTE_UNUSED,
+ symbolS *to_symbol ATTRIBUTE_UNUSED)
{
}
void
-md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
- char *ptr ATTRIBUTE_UNUSED;
- addressT from_addr ATTRIBUTE_UNUSED;
- addressT to_addr ATTRIBUTE_UNUSED;
- fragS *frag ATTRIBUTE_UNUSED;
- symbolS *to_symbol ATTRIBUTE_UNUSED;
+md_create_long_jump (char *ptr ATTRIBUTE_UNUSED,
+ addressT from_addr ATTRIBUTE_UNUSED,
+ addressT to_addr ATTRIBUTE_UNUSED,
+ fragS *frag ATTRIBUTE_UNUSED,
+ symbolS *to_symbol ATTRIBUTE_UNUSED)
{
}
static int
-set_option (arg)
- char *arg;
-{
- int yes = 1;
-
- if (strcmp (arg, "all-extensions") == 0 ||
- strcmp (arg, "all") == 0)
- {
- memset (pdp11_extension, ~0, sizeof pdp11_extension);
- pdp11_extension[PDP11_NONE] = 0;
- return 1;
- }
- else if (strcmp (arg, "no-extensions") == 0)
- {
- memset (pdp11_extension, 0, sizeof pdp11_extension);
- pdp11_extension[PDP11_BASIC] = 1;
- return 1;
- }
-
- if (strncmp (arg, "no-", 3) == 0)
- {
- yes = 0;
- arg += 3;
- }
-
- if (strcmp (arg, "cis") == 0) /* commersial instructions */
- pdp11_extension[PDP11_CIS] = yes;
- else if (strcmp (arg, "csm") == 0) /* call supervisor mode */
- pdp11_extension[PDP11_CSM] = yes;
- else if (strcmp (arg, "eis") == 0) /* extended instruction set */
- pdp11_extension[PDP11_EIS] = pdp11_extension[PDP11_LEIS] = yes;
- else if (strcmp (arg, "fis") == 0 || /* KEV11 floating-point */
- strcmp (arg, "kev11") == 0 ||
- strcmp (arg, "kev-11") == 0)
- pdp11_extension[PDP11_FIS] = yes;
- else if (strcmp (arg, "fpp") == 0 || /* FP-11 floating-point */
- strcmp (arg, "fpu") == 0 ||
- strcmp (arg, "fp11") == 0 ||
- strcmp (arg, "fp-11") == 0 ||
- strcmp (arg, "fpj11") == 0 ||
- strcmp (arg, "fp-j11") == 0 ||
- strcmp (arg, "fpj-11") == 0)
- pdp11_extension[PDP11_FPP] = yes;
- else if (strcmp (arg, "limited-eis") == 0) /* limited extended insns */
- {
- pdp11_extension[PDP11_LEIS] = yes;
- if (!pdp11_extension[PDP11_LEIS])
- pdp11_extension[PDP11_EIS] = 0;
- }
- else if (strcmp (arg, "mfpt") == 0) /* move from processor type */
- pdp11_extension[PDP11_MFPT] = yes;
- else if (strncmp (arg, "mproc", 5) == 0 || /* multiprocessor insns: */
- strncmp (arg, "multiproc", 9) == 0 ) /* TSTSET, WRTLCK */
- pdp11_extension[PDP11_MPROC] = yes;
- else if (strcmp (arg, "mxps") == 0) /* move from/to proc status */
- pdp11_extension[PDP11_MXPS] = yes;
- else if (strcmp (arg, "pic") == 0) /* position-independent code */
- asm_option[ASM_OPT_PIC] = yes;
- else if (strcmp (arg, "spl") == 0) /* set priority level */
- pdp11_extension[PDP11_SPL] = yes;
- else if (strcmp (arg, "ucode") == 0 || /* microcode instructions: */
- strcmp (arg, "microcode") == 0) /* LDUB, MED, XFC */
- pdp11_extension[PDP11_UCODE] = yes;
- else
- return 0;
-
- return 1;
-}
-
-static int
-set_cpu_model (arg)
- char *arg;
+set_cpu_model (char *arg)
{
char buf[4];
char *model = buf;
@@ -1082,8 +1066,7 @@ set_cpu_model (arg)
if (model[-1] == 'd')
{
- if (arg[0] == 'f' ||
- arg[0] == 'j')
+ if (arg[0] == 'f' || arg[0] == 'j')
model[-1] = *arg++;
}
else if (model[-1] == 'x')
@@ -1105,7 +1088,7 @@ set_cpu_model (arg)
return 0;
}
- /* allow up to two revision letters */
+ /* Allow up to two revision letters. */
if (arg[0] != 0)
*model++ = *arg++;
if (arg[0] != 0)
@@ -1115,70 +1098,80 @@ set_cpu_model (arg)
set_option ("no-extensions");
- if (strncmp (buf, "a", 1) == 0) /* KA11 (11/15/20) */
- return 1; /* no extensions */
+ /* KA11 (11/15/20). */
+ if (strncmp (buf, "a", 1) == 0)
+ return 1; /* No extensions. */
- else if (strncmp (buf, "b", 1) == 0) /* KB11 (11/45/50/55/70) */
- return set_option ("eis") &&
- set_option ("spl");
+ /* KB11 (11/45/50/55/70). */
+ else if (strncmp (buf, "b", 1) == 0)
+ return set_option ("eis") && set_option ("spl");
- else if (strncmp (buf, "da", 2) == 0) /* KD11-A (11/35/40) */
+ /* KD11-A (11/35/40). */
+ else if (strncmp (buf, "da", 2) == 0)
return set_option ("limited-eis");
- else if (strncmp (buf, "db", 2) == 0 || /* KD11-B (11/05/10) */
- strncmp (buf, "dd", 2) == 0) /* KD11-D (11/04) */
+ /* KD11-B (11/05/10). */
+ else if (strncmp (buf, "db", 2) == 0
+ /* KD11-D (11/04). */
+ || strncmp (buf, "dd", 2) == 0)
return 1; /* no extensions */
- else if (strncmp (buf, "de", 2) == 0) /* KD11-E (11/34) */
- return set_option ("eis") &&
- set_option ("mxps");
-
- else if (strncmp (buf, "df", 2) == 0 || /* KD11-F (11/03) */
- strncmp (buf, "dh", 2) == 0 || /* KD11-H (11/03) */
- strncmp (buf, "dq", 2) == 0) /* KD11-Q (11/03) */
- return set_option ("limited-eis") &&
- set_option ("mxps");
-
- else if (strncmp (buf, "dk", 2) == 0) /* KD11-K (11/60) */
- return set_option ("eis") &&
- set_option ("mxps") &&
- set_option ("ucode");
-
- else if (strncmp (buf, "dz", 2) == 0) /* KD11-Z (11/44) */
- return set_option ("csm") &&
- set_option ("eis") &&
- set_option ("mfpt") &&
- set_option ("mxps") &&
- set_option ("spl");
-
- else if (strncmp (buf, "f", 1) == 0) /* F11 (11/23/24) */
- return set_option ("eis") &&
- set_option ("mfpt") &&
- set_option ("mxps");
-
- else if (strncmp (buf, "j", 1) == 0) /* J11 (11/53/73/83/84/93/94)*/
- return set_option ("csm") &&
- set_option ("eis") &&
- set_option ("mfpt") &&
- set_option ("multiproc") &&
- set_option ("mxps") &&
- set_option ("spl");
-
- else if (strncmp (buf, "t", 1) == 0) /* T11 (11/21) */
- return set_option ("limited-eis") &&
- set_option ("mxps");
+ /* KD11-E (11/34). */
+ else if (strncmp (buf, "de", 2) == 0)
+ return set_option ("eis") && set_option ("mxps");
+
+ /* KD11-F (11/03). */
+ else if (strncmp (buf, "df", 2) == 0
+ /* KD11-H (11/03). */
+ || strncmp (buf, "dh", 2) == 0
+ /* KD11-Q (11/03). */
+ || strncmp (buf, "dq", 2) == 0)
+ return set_option ("limited-eis") && set_option ("mxps");
+
+ /* KD11-K (11/60). */
+ else if (strncmp (buf, "dk", 2) == 0)
+ return set_option ("eis")
+ && set_option ("mxps")
+ && set_option ("ucode");
+
+ /* KD11-Z (11/44). */
+ else if (strncmp (buf, "dz", 2) == 0)
+ return set_option ("csm")
+ && set_option ("eis")
+ && set_option ("mfpt")
+ && set_option ("mxps")
+ && set_option ("spl");
+
+ /* F11 (11/23/24). */
+ else if (strncmp (buf, "f", 1) == 0)
+ return set_option ("eis")
+ && set_option ("mfpt")
+ && set_option ("mxps");
+
+ /* J11 (11/53/73/83/84/93/94). */
+ else if (strncmp (buf, "j", 1) == 0)
+ return set_option ("csm")
+ && set_option ("eis")
+ && set_option ("mfpt")
+ && set_option ("multiproc")
+ && set_option ("mxps")
+ && set_option ("spl");
+
+ /* T11 (11/21). */
+ else if (strncmp (buf, "t", 1) == 0)
+ return set_option ("limited-eis")
+ && set_option ("mxps");
else
return 0;
}
static int
-set_machine_model (arg)
- char *arg;
+set_machine_model (char *arg)
{
- if (strncmp (arg, "pdp-11/", 7) != 0 &&
- strncmp (arg, "pdp11/", 6) != 0 &&
- strncmp (arg, "11/", 3) != 0)
+ if (strncmp (arg, "pdp-11/", 7) != 0
+ && strncmp (arg, "pdp11/", 6) != 0
+ && strncmp (arg, "11/", 3) != 0)
return 0;
if (strncmp (arg, "pdp", 3) == 0)
@@ -1188,56 +1181,56 @@ set_machine_model (arg)
if (strncmp (arg, "11/", 3) == 0)
arg += 3;
- if (strcmp (arg, "03") == 0) /* 11/03 */
- return set_cpu_model ("kd11f"); /* KD11-F */
+ if (strcmp (arg, "03") == 0)
+ return set_cpu_model ("kd11f");
+
+ else if (strcmp (arg, "04") == 0)
+ return set_cpu_model ("kd11d");
- else if (strcmp (arg, "04") == 0) /* 11/04 */
- return set_cpu_model ("kd11d"); /* KD11-D */
+ else if (strcmp (arg, "05") == 0
+ || strcmp (arg, "10") == 0)
+ return set_cpu_model ("kd11b");
- else if (strcmp (arg, "05") == 0 || /* 11/05 or 11/10 */
- strcmp (arg, "10") == 0)
- return set_cpu_model ("kd11b"); /* KD11-B */
+ else if (strcmp (arg, "15") == 0
+ || strcmp (arg, "20") == 0)
+ return set_cpu_model ("ka11");
- else if (strcmp (arg, "15") == 0 || /* 11/15 or 11/20 */
- strcmp (arg, "20") == 0)
- return set_cpu_model ("ka11"); /* KA11 */
+ else if (strcmp (arg, "21") == 0)
+ return set_cpu_model ("t11");
- else if (strcmp (arg, "21") == 0) /* 11/21 */
- return set_cpu_model ("t11"); /* T11 */
+ else if (strcmp (arg, "23") == 0
+ || strcmp (arg, "24") == 0)
+ return set_cpu_model ("f11");
- else if (strcmp (arg, "23") == 0 || /* 11/23 or 11/24 */
- strcmp (arg, "24") == 0)
- return set_cpu_model ("f11"); /* F11 */
+ else if (strcmp (arg, "34") == 0
+ || strcmp (arg, "34a") == 0)
+ return set_cpu_model ("kd11e");
- else if (strcmp (arg, "34") == 0 || /* 11/34 or 11/34a */
- strcmp (arg, "34a") == 0)
- return set_cpu_model ("kd11e"); /* KD11-E */
+ else if (strcmp (arg, "35") == 0
+ || strcmp (arg, "40") == 0)
+ return set_cpu_model ("kd11da");
- else if (strcmp (arg, "35") == 0 || /* 11/35 or 11/40 */
- strcmp (arg, "40") == 0)
- return set_cpu_model ("kd11da"); /* KD11-A */
+ else if (strcmp (arg, "44") == 0)
+ return set_cpu_model ("kd11dz");
- else if (strcmp (arg, "44") == 0) /* 11/44 */
- return set_cpu_model ("kd11dz"); /* KD11-Z */
+ else if (strcmp (arg, "45") == 0
+ || strcmp (arg, "50") == 0
+ || strcmp (arg, "55") == 0
+ || strcmp (arg, "70") == 0)
+ return set_cpu_model ("kb11");
- else if (strcmp (arg, "45") == 0 || /* 11/45/50/55/70 */
- strcmp (arg, "50") == 0 ||
- strcmp (arg, "55") == 0 ||
- strcmp (arg, "70") == 0)
- return set_cpu_model ("kb11"); /* KB11 */
+ else if (strcmp (arg, "60") == 0)
+ return set_cpu_model ("kd11k");
- else if (strcmp (arg, "60") == 0) /* 11/60 */
- return set_cpu_model ("kd11k"); /* KD11-K */ /* FPP? */
+ else if (strcmp (arg, "53") == 0
+ || strcmp (arg, "73") == 0
+ || strcmp (arg, "83") == 0
+ || strcmp (arg, "84") == 0
+ || strcmp (arg, "93") == 0
+ || strcmp (arg, "94") == 0)
+ return set_cpu_model ("j11")
+ && set_option ("fpp");
- else if (strcmp (arg, "53") == 0 || /* 11/53/73/83/84/93/94 */
- strcmp (arg, "73") == 0 ||
- strcmp (arg, "83") == 0 ||
- strcmp (arg, "84") == 0 ||
- strcmp (arg, "93") == 0 ||
- strcmp (arg, "94") == 0)
- return set_cpu_model ("j11") && /* J11 */
- set_option ("fpp"); /* All J11 machines come */
- /* with FPP installed. */
else
return 0;
}
@@ -1257,16 +1250,11 @@ struct option md_longopts[] =
size_t md_longopts_size = sizeof (md_longopts);
-/*
- * md_parse_option
- * Invocation line includes a switch not recognized by the base assembler.
- * See if it's a processor-specific option.
- */
+/* Invocation line includes a switch not recognized by the base assembler.
+ See if it's a processor-specific option. */
int
-md_parse_option (c, arg)
- int c;
- char *arg;
+md_parse_option (int c, char *arg)
{
init_defaults ();
@@ -1303,249 +1291,8 @@ md_parse_option (c, arg)
return 0;
}
-/*
-One possible way of parsing options.
-
-enum
-{
- OPTION_CSM,
- OPTION_CIS,
- ...
-};
-
-struct
-{
- const char *pattern;
- int opt;
- const char *description;
-} options;
-
-static struct options extension_opts[] =
-{
- { "Ncsm", OPTION_CSM,
- "allow (disallow) CSM instruction" },
- { "Ncis", OPTION_CIS,
- "allow (disallow) commersial instruction set" },
- { "Neis", OPTION_EIS,
- "allow (disallow) extended instruction set" },
- ...
- { "all-extensions", OPTION_ALL_EXTENSIONS,
- "allow all instruction set extensions\n\
- (this is the default)" },
- { "no-extensions", OPTION_NO_EXTENSIONS,
- "disallow all instruction set extensions" },
- { "pic", OPTION_PIC,
- "position-independent code" },
-};
-
-static struct options cpu_opts[] =
-{
- { "Ka_11_*", OPTION_KA11, "KA11 CPU. ..." },
- { "Kb_11_*", OPTION_KB11, "KB11 CPU. ..." },
- { "Kd_11_a*", OPTION_KD11A, "KD11-A CPU. ..." },
- { "Kd_11_b*", OPTION_KD11B, "KD11-B CPU. ..." },
- { "Kd_11_d*", OPTION_KD11D, "KD11-D CPU. ..." },
- { "Kd_11_e*", OPTION_KD11E, "KD11-E CPU. ..." },
- { "Kd_11_f*", OPTION_KD11F, "KD11-F CPU. ..." },
- { "Kd_11_h*", OPTION_KD11H, "KD11-H CPU. ..." },
- { "Kd_11_q*", OPTION_KD11Q, "KD11-Q CPU. ..." },
- { "Kd_11_z*", OPTION_KD11Z, "KD11-Z CPU. ..." },
- { "Df_11_*", OPTION_F11, "F11 CPU. ..." },
- { "Dj_11_*", OPTION_J11, "J11 CPU. ..." },
- { "Dt_11_*", OPTION_T11, "T11 CPU. ..." },
-};
-
-static struct options model_opts[] =
-{
- { "P03", OPTION_PDP11_03, "same as ..." },
- { "P04", OPTION_PDP11_04, "same as ..." },
- { "P05", OPTION_PDP11_05, "same as ..." },
- { "P10", OPTION_PDP11_10, "same as ..." },
- { "P15", OPTION_PDP11_15, "same as ..." },
- { "P20", OPTION_PDP11_20, "same as ..." },
- { "P21", OPTION_PDP11_21, "same as ..." },
- { "P24", OPTION_PDP11_24, "same as ..." },
- { "P34", OPTION_PDP11_34, "same as ..." },
- { "P34a", OPTION_PDP11_34A, "same as ..." },
- { "P40", OPTION_PDP11_40, "same as ..." },
- { "P44", OPTION_PDP11_44, "same as ..." },
- { "P45", OPTION_PDP11_45, "same as ..." },
- { "P50", OPTION_PDP11_50, "same as ..." },
- { "P53", OPTION_PDP11_53, "same as ..." },
- { "P55", OPTION_PDP11_55, "same as ..." },
- { "P60", OPTION_PDP11_60, "same as ..." },
- { "P70", OPTION_PDP11_70, "same as ..." },
- { "P73", OPTION_PDP11_73, "same as ..." },
- { "P83", OPTION_PDP11_83, "same as ..." },
- { "P84", OPTION_PDP11_84, "same as ..." },
- { "P93", OPTION_PDP11_93, "same as ..." },
- { "P94", OPTION_PDP11_94, "same as ..." },
-};
-
-struct
-{
- const char *title;
- struct options *opts;
- int num;
-} all_opts[] =
-{
- { "PDP-11 instruction set extentions",
- extension_opts,
- sizeof extension_opts / sizeof extension_opts[0] },
- { "PDP-11 CPU model options",
- cpu_opts,
- sizeof cpu_opts / sizeof cpu_opts[0] },
- { "PDP-11 machine model options",
- model_opts,
- sizeof model_opts / sizeof model_opts[0] },
-};
-
-int
-parse_match (char *arg, char *pattern)
-{
- int yes = 1;
-
- while (*pattern)
- {
- switch (*pattern++)
- {
- case 'N':
- if (strncmp (arg, "no-") == 0)
- {
- yes = 0;
- arg += 3;
- }
- break;
-
- case 'K':
- if (arg[0] == 'k')
- arg++;
- break;
-
- case 'D':
- if (strncmp (arg, "kd", 2) == 0)
- arg +=2;
- break;
-
- case 'P':
- if (strncmp (arg, "pdp-11/", 7) == 0)
- arg += 7;
- else if (strncmp (arg, "pdp11/", 6) == 0)
- arg += 6;
- else if (strncmp (arg, "11/", 3) == 0)
- arg += 3;
- break;
-
- case '_':
- if (arg[0] == "-")
- {
- if (*++arg == 0)
- return 0;
- }
- break;
-
- case '*':
- return 1;
-
- default:
- if (*arg++ != pattern[-1])
- return 0;
- }
- }
-
- return arg[0] == 0;
-}
-
-int
-fprint_opt (stream, pattern)
- FILE *stream;
- const char *pattern;
-{
- int n;
-
- while (*pattern)
- {
- switch (*pattern++)
- {
- case 'N':
- n += fprintf (stream, "(no-)");
- break;
-
- case 'K':
- n += fprintf (stream, "k");
- break;
-
- case 'P':
- n += fprintf (stream "11/");
- break;
-
- case 'D':
- case '_':
- case '*':
- break;
-
- default:
- fputc (pattern[-1], stream);
- n++;
- }
- }
-
- return n;
-}
-
-int
-parse_option (char *arg)
-{
- int i, j;
-
- for (i = 0; i < sizeof all_opts / sizeof all_opts[0]; i++)
- {
- for (j = 0; j < all_opts[i].num; j++)
- {
- if (parse_match (arg, all_opts[i].opts[j].pattern))
- {
- set_option (all_opts[i].opts[j].opt);
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-static void
-fprint_space (stream, n)
- FILE *stream;
- int n;
-{
- while (n--)
- fputc (' ', stream);
-}
-
void
-md_show_usage (stream)
- FILE *stream;
-{
- int i, j, n;
-
- for (i = 0; i < sizeof all_opts / sizeof all_opts[0]; i++)
- {
- fprintf (stream "\n%s:\n\n", all_opts[i].title);
-
- for (j = 0; j < all_opts[i].num; j++)
- {
- fprintf (stream, "-m");
- n = fprintf_opt (stream, all_opts[i].opts[j].pattern);
- fprint_space (stream, 22 - n);
- fprintf (stream, "%s\n", all_opts[i].opts[j].description);
- }
- }
-}
-*/
-
-void
-md_show_usage (stream)
- FILE *stream;
+md_show_usage (FILE *stream)
{
fprintf (stream, "\
\n\
@@ -1619,40 +1366,37 @@ PDP-11 machine model options:\n\
}
symbolS *
-md_undefined_symbol (name)
- char *name ATTRIBUTE_UNUSED;
+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
{
return 0;
}
valueT
-md_section_align (segment, size)
- segT segment ATTRIBUTE_UNUSED;
- valueT size;
+md_section_align (segT segment ATTRIBUTE_UNUSED,
+ valueT size)
{
return (size + 1) & ~1;
}
long
-md_pcrel_from (fixP)
- fixS *fixP;
+md_pcrel_from (fixS *fixP)
{
return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
}
/* Translate internal representation of relocation info to BFD target
format. */
+
arelent *
-tc_gen_reloc (section, fixp)
- asection *section ATTRIBUTE_UNUSED;
- fixS *fixp;
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
+ fixS *fixp)
{
arelent *reloc;
bfd_reloc_code_real_type code;
- reloc = (arelent *) xmalloc (sizeof (arelent));
+ reloc = xmalloc (sizeof (* reloc));
- reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
@@ -1691,8 +1435,7 @@ tc_gen_reloc (section, fixp)
}
void
-pseudo_bss (c)
- int c ATTRIBUTE_UNUSED;
+pseudo_bss (int c ATTRIBUTE_UNUSED)
{
int temp;
@@ -1702,12 +1445,9 @@ pseudo_bss (c)
}
void
-pseudo_even (c)
- int c ATTRIBUTE_UNUSED;
+pseudo_even (int c ATTRIBUTE_UNUSED)
{
int alignment = 1; /* 2^1 */
frag_align (alignment, 0, 1);
record_alignment (now_seg, alignment);
}
-
-/* end of tc-pdp11.c */
diff --git a/gas/config/tc-tic30.c b/gas/config/tc-tic30.c
index 7234741..40baefc 100644
--- a/gas/config/tc-tic30.c
+++ b/gas/config/tc-tic30.c
@@ -37,33 +37,35 @@
/* Put here all non-digit non-letter characters that may occur in an
operand. */
static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
-static char *ordinal_names[] = {
+static char *ordinal_names[] =
+{
"first", "second", "third", "fourth", "fifth"
};
const int md_reloc_size = 0;
-const char comment_chars[] = ";";
-const char line_comment_chars[] = "*";
+const char comment_chars[] = ";";
+const char line_comment_chars[] = "*";
const char line_separator_chars[] = "";
const char *md_shortopts = "";
-struct option md_longopts[] = {
+struct option md_longopts[] =
+{
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof (md_longopts);
-/* Chars that mean this number is a floating point constant. */
-/* As in 0f12.456 */
-/* or 0d1.2345e12 */
+/* Chars that mean this number is a floating point constant.
+ As in 0f12.456
+ or 0d1.2345e12. */
const char FLT_CHARS[] = "fFdDxX";
/* Chars that can be used to separate mant from exp in floating point
nums. */
const char EXP_CHARS[] = "eE";
-/* tables for lexical analysis */
+/* Tables for lexical analysis. */
static char opcode_chars[256];
static char register_chars[256];
static char operand_chars[256];
@@ -71,22 +73,21 @@ static char space_chars[256];
static char identifier_chars[256];
static char digit_chars[256];
-/* lexical macros */
-#define is_opcode_char(x) (opcode_chars[(unsigned char) x])
-#define is_operand_char(x) (operand_chars[(unsigned char) x])
-#define is_register_char(x) (register_chars[(unsigned char) x])
-#define is_space_char(x) (space_chars[(unsigned char) x])
-#define is_identifier_char(x) (identifier_chars[(unsigned char) x])
-#define is_digit_char(x) (digit_chars[(unsigned char) x])
+/* Lexical macros. */
+#define is_opcode_char(x) (opcode_chars [(unsigned char) x])
+#define is_operand_char(x) (operand_chars [(unsigned char) x])
+#define is_register_char(x) (register_chars [(unsigned char) x])
+#define is_space_char(x) (space_chars [(unsigned char) x])
+#define is_identifier_char(x) (identifier_chars [(unsigned char) x])
+#define is_digit_char(x) (digit_chars [(unsigned char) x])
-const pseudo_typeS md_pseudo_table[] = {
+const pseudo_typeS md_pseudo_table[] =
+{
{0, 0, 0}
};
-int debug PARAMS ((const char *string, ...));
-
-int
-debug VPARAMS ((const char *string, ...))
+static int
+debug (const char *string, ...)
{
if (flag_debug)
{
@@ -105,64 +106,85 @@ debug VPARAMS ((const char *string, ...))
return 0;
}
-/* hash table for opcode lookup */
+/* Hash table for opcode lookup. */
static struct hash_control *op_hash;
-/* hash table for parallel opcode lookup */
+/* Hash table for parallel opcode lookup. */
static struct hash_control *parop_hash;
-/* hash table for register lookup */
+/* Hash table for register lookup. */
static struct hash_control *reg_hash;
-/* hash table for indirect addressing lookup */
+/* Hash table for indirect addressing lookup. */
static struct hash_control *ind_hash;
void
-md_begin ()
+md_begin (void)
{
const char *hash_err;
+
debug ("In md_begin()\n");
op_hash = hash_new ();
+
{
const template *current_optab = tic30_optab;
+
for (; current_optab < tic30_optab_end; current_optab++)
{
- hash_err = hash_insert (op_hash, current_optab->name, (char *) current_optab);
+ hash_err = hash_insert (op_hash, current_optab->name,
+ (char *) current_optab);
if (hash_err)
- as_fatal ("Internal Error: Can't Hash %s: %s", current_optab->name, hash_err);
+ as_fatal ("Internal Error: Can't Hash %s: %s",
+ current_optab->name, hash_err);
}
}
+
parop_hash = hash_new ();
+
{
const partemplate *current_parop = tic30_paroptab;
+
for (; current_parop < tic30_paroptab_end; current_parop++)
{
- hash_err = hash_insert (parop_hash, current_parop->name, (char *) current_parop);
+ hash_err = hash_insert (parop_hash, current_parop->name,
+ (char *) current_parop);
if (hash_err)
- as_fatal ("Internal Error: Can't Hash %s: %s", current_parop->name, hash_err);
+ as_fatal ("Internal Error: Can't Hash %s: %s",
+ current_parop->name, hash_err);
}
}
+
reg_hash = hash_new ();
+
{
const reg *current_reg = tic30_regtab;
+
for (; current_reg < tic30_regtab_end; current_reg++)
{
- hash_err = hash_insert (reg_hash, current_reg->name, (char *) current_reg);
+ hash_err = hash_insert (reg_hash, current_reg->name,
+ (char *) current_reg);
if (hash_err)
- as_fatal ("Internal Error: Can't Hash %s: %s", current_reg->name, hash_err);
+ as_fatal ("Internal Error: Can't Hash %s: %s",
+ current_reg->name, hash_err);
}
}
+
ind_hash = hash_new ();
+
{
const ind_addr_type *current_ind = tic30_indaddr_tab;
+
for (; current_ind < tic30_indaddrtab_end; current_ind++)
{
- hash_err = hash_insert (ind_hash, current_ind->syntax, (char *) current_ind);
+ hash_err = hash_insert (ind_hash, current_ind->syntax,
+ (char *) current_ind);
if (hash_err)
- as_fatal ("Internal Error: Can't Hash %s: %s", current_ind->syntax, hash_err);
+ as_fatal ("Internal Error: Can't Hash %s: %s",
+ current_ind->syntax, hash_err);
}
}
- /* fill in lexical tables: opcode_chars, operand_chars, space_chars */
+
+ /* Fill in lexical tables: opcode_chars, operand_chars, space_chars. */
{
- register int c;
- register char *p;
+ int c;
+ char *p;
for (c = 0; c < 256; c++)
{
@@ -177,17 +199,20 @@ md_begin ()
register_chars[c] = opcode_chars[c];
}
else if (c == ')' || c == '(')
- {
- register_chars[c] = c;
- }
+ register_chars[c] = c;
+
if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
operand_chars[c] = c;
+
if (ISDIGIT (c) || c == '-')
digit_chars[c] = c;
+
if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
identifier_chars[c] = c;
+
if (c == ' ' || c == '\t')
space_chars[c] = c;
+
if (c == '_')
opcode_chars[c] = c;
}
@@ -196,34 +221,39 @@ md_begin ()
}
}
-/* Address Mode OR values */
+/* Address Mode OR values. */
#define AM_Register 0x00000000
#define AM_Direct 0x00200000
#define AM_Indirect 0x00400000
#define AM_Immediate 0x00600000
#define AM_NotReq 0xFFFFFFFF
-/* PC Relative OR values */
+/* PC Relative OR values. */
#define PC_Register 0x00000000
#define PC_Relative 0x02000000
-typedef struct {
+typedef struct
+{
unsigned op_type;
- struct {
+ struct
+ {
int resolved;
unsigned address;
char *label;
expressionS direct_expr;
} direct;
- struct {
+ struct
+ {
unsigned mod;
int ARnum;
unsigned char disp;
} indirect;
- struct {
+ struct
+ {
unsigned opcode;
} reg;
- struct {
+ struct
+ {
int resolved;
int decimal_found;
float f_number;
@@ -234,564 +264,403 @@ typedef struct {
} immediate;
} operand;
-int tic30_parallel_insn PARAMS ((char *));
-operand *tic30_operand PARAMS ((char *));
-char *tic30_find_parallel_insn PARAMS ((char *, char *));
-
template *opcode;
-struct tic30_insn {
- template *tm; /* Template of current instruction */
- unsigned opcode; /* Final opcode */
- unsigned int operands; /* Number of given operands */
- /* Type of operand given in instruction */
+struct tic30_insn
+{
+ template *tm; /* Template of current instruction. */
+ unsigned opcode; /* Final opcode. */
+ unsigned int operands; /* Number of given operands. */
+ /* Type of operand given in instruction. */
operand *operand_type[MAX_OPERANDS];
- unsigned addressing_mode; /* Final addressing mode of instruction */
+ unsigned addressing_mode; /* Final addressing mode of instruction. */
};
struct tic30_insn insn;
static int found_parallel_insn;
-void
-md_assemble (line)
- char *line;
-{
- template *opcode;
- char *current_posn;
- char *token_start;
- char save_char;
- unsigned int count;
+static char output_invalid_buf[8];
- debug ("In md_assemble() with argument %s\n", line);
- memset (&insn, '\0', sizeof (insn));
- if (found_parallel_insn)
- {
- debug ("Line is second part of parallel instruction\n\n");
- found_parallel_insn = 0;
- return;
- }
- if ((current_posn = tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
- current_posn = line;
+static char *
+output_invalid (char c)
+{
+ if (ISPRINT (c))
+ sprintf (output_invalid_buf, "'%c'", c);
else
- found_parallel_insn = 1;
- while (is_space_char (*current_posn))
- current_posn++;
- token_start = current_posn;
- if (!is_opcode_char (*current_posn))
- {
- as_bad ("Invalid character %s in opcode", output_invalid (*current_posn));
- return;
- }
- /* Check if instruction is a parallel instruction by seeing if the first
- character is a q. */
- if (*token_start == 'q')
+ sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
+ return output_invalid_buf;
+}
+
+/* next_line points to the next line after the current instruction
+ (current_line). Search for the parallel bars, and if found, merge two
+ lines into internal syntax for a parallel instruction:
+ q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
+ By this stage, all comments are scrubbed, and only the bare lines are
+ given. */
+
+#define NONE 0
+#define START_OPCODE 1
+#define END_OPCODE 2
+#define START_OPERANDS 3
+#define END_OPERANDS 4
+
+static char *
+tic30_find_parallel_insn (char *current_line, char *next_line)
+{
+ int found_parallel = 0;
+ char first_opcode[256];
+ char second_opcode[256];
+ char first_operands[256];
+ char second_operands[256];
+ char *parallel_insn;
+
+ debug ("In tic30_find_parallel_insn()\n");
+ while (!is_end_of_line[(unsigned char) *next_line])
{
- if (tic30_parallel_insn (token_start))
+ if (*next_line == PARALLEL_SEPARATOR
+ && *(next_line + 1) == PARALLEL_SEPARATOR)
{
- if (found_parallel_insn)
- free (token_start);
- return;
+ found_parallel = 1;
+ next_line++;
+ break;
}
+ next_line++;
}
- while (is_opcode_char (*current_posn))
- current_posn++;
- { /* Find instruction */
- save_char = *current_posn;
- *current_posn = '\0';
- opcode = (template *) hash_find (op_hash, token_start);
- if (opcode)
- {
- debug ("Found instruction %s\n", opcode->name);
- insn.tm = opcode;
- }
- else
+ if (!found_parallel)
+ return NULL;
+ debug ("Found a parallel instruction\n");
+
+ {
+ int i;
+ char *opcode, *operands, *line;
+
+ for (i = 0; i < 2; i++)
{
- debug ("Didn't find insn\n");
- as_bad ("Unknown TMS320C30 instruction: %s", token_start);
- return;
- }
- *current_posn = save_char;
- }
- if (*current_posn != END_OF_INSN)
- { /* Find operands */
- int paren_not_balanced;
- int expecting_operand = 0;
- int this_operand;
- do
+ if (i == 0)
+ {
+ opcode = &first_opcode[0];
+ operands = &first_operands[0];
+ line = current_line;
+ }
+ else
+ {
+ opcode = &second_opcode[0];
+ operands = &second_operands[0];
+ line = next_line;
+ }
+
{
- /* skip optional white space before operand */
- while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
- {
- if (!is_space_char (*current_posn))
- {
- as_bad ("Invalid character %s before %s operand",
- output_invalid (*current_posn),
- ordinal_names[insn.operands]);
- return;
- }
- current_posn++;
- }
- token_start = current_posn; /* after white space */
- paren_not_balanced = 0;
- while (paren_not_balanced || *current_posn != ',')
+ int search_status = NONE;
+ int char_ptr = 0;
+ char c;
+
+ while (!is_end_of_line[(unsigned char) (c = *line)])
{
- if (*current_posn == END_OF_INSN)
- {
- if (paren_not_balanced)
- {
- as_bad ("Unbalanced parenthesis in %s operand.",
- ordinal_names[insn.operands]);
- return;
- }
- else
- break; /* we are done */
- }
- else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
- {
- as_bad ("Invalid character %s in %s operand",
- output_invalid (*current_posn),
- ordinal_names[insn.operands]);
- return;
- }
- if (*current_posn == '(')
- ++paren_not_balanced;
- if (*current_posn == ')')
- --paren_not_balanced;
- current_posn++;
- }
- if (current_posn != token_start)
- { /* yes, we've read in another operand */
- this_operand = insn.operands++;
- if (insn.operands > MAX_OPERANDS)
+ if (is_opcode_char (c) && search_status == NONE)
{
- as_bad ("Spurious operands; (%d operands/instruction max)",
- MAX_OPERANDS);
- return;
+ opcode[char_ptr++] = TOLOWER (c);
+ search_status = START_OPCODE;
}
- /* now parse operand adding info to 'insn' as we go along */
- save_char = *current_posn;
- *current_posn = '\0';
- insn.operand_type[this_operand] = tic30_operand (token_start);
- *current_posn = save_char;
- if (insn.operand_type[this_operand] == NULL)
- return;
- }
- else
- {
- if (expecting_operand)
+ else if (is_opcode_char (c) && search_status == START_OPCODE)
+ opcode[char_ptr++] = TOLOWER (c);
+ else if (!is_opcode_char (c) && search_status == START_OPCODE)
{
- as_bad ("Expecting operand after ','; got nothing");
- return;
+ opcode[char_ptr] = '\0';
+ char_ptr = 0;
+ search_status = END_OPCODE;
}
- if (*current_posn == ',')
+ else if (is_operand_char (c) && search_status == START_OPERANDS)
+ operands[char_ptr++] = c;
+
+ if (is_operand_char (c) && search_status == END_OPCODE)
{
- as_bad ("Expecting operand before ','; got nothing");
- return;
- }
- }
- /* now *current_posn must be either ',' or END_OF_INSN */
- if (*current_posn == ',')
- {
- if (*++current_posn == END_OF_INSN)
- { /* just skip it, if it's \n complain */
- as_bad ("Expecting operand after ','; got nothing");
- return;
+ operands[char_ptr++] = c;
+ search_status = START_OPERANDS;
}
- expecting_operand = 1;
+
+ line++;
}
+ if (search_status != START_OPERANDS)
+ return NULL;
+ operands[char_ptr] = '\0';
}
- while (*current_posn != END_OF_INSN); /* until we get end of insn */
- }
- debug ("Number of operands found: %d\n", insn.operands);
- /* Check that number of operands is correct */
- if (insn.operands != insn.tm->operands)
+ }
+ }
+ parallel_insn = malloc (strlen (first_opcode) + strlen (first_operands)
+ + strlen (second_opcode) + strlen (second_operands) + 8);
+ sprintf (parallel_insn, "q_%s_%s %s | %s",
+ first_opcode, second_opcode,
+ first_operands, second_operands);
+ debug ("parallel insn = %s\n", parallel_insn);
+ return parallel_insn;
+}
+
+#undef NONE
+#undef START_OPCODE
+#undef END_OPCODE
+#undef START_OPERANDS
+#undef END_OPERANDS
+
+static operand *
+tic30_operand (char *token)
+{
+ unsigned int count;
+ char ind_buffer[strlen (token)];
+ operand *current_op;
+
+ debug ("In tic30_operand with %s\n", token);
+ current_op = malloc (sizeof (* current_op));
+ memset (current_op, '\0', sizeof (operand));
+
+ if (*token == DIRECT_REFERENCE)
{
- unsigned int i;
- unsigned int numops = insn.tm->operands;
- /* If operands are not the same, then see if any of the operands are not
- required. Then recheck with number of given operands. If they are still not
- the same, then give an error, otherwise carry on. */
- for (i = 0; i < insn.tm->operands; i++)
- if (insn.tm->operand_types[i] & NotReq)
- numops--;
- if (insn.operands != numops)
+ char *token_posn = token + 1;
+ int direct_label = 0;
+
+ debug ("Found direct reference\n");
+ while (*token_posn)
{
- as_bad ("Incorrect number of operands given");
- return;
+ if (!is_digit_char (*token_posn))
+ direct_label = 1;
+ token_posn++;
}
- }
- insn.addressing_mode = AM_NotReq;
- for (count = 0; count < insn.operands; count++)
- {
- if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
+
+ if (direct_label)
{
- debug ("Operand %d matches\n", count + 1);
- /* If instruction has two operands and has an AddressMode modifier then set
- addressing mode type for instruction */
- if (insn.tm->opcode_modifier == AddressMode)
+ char *save_input_line_pointer;
+ segT retval;
+
+ debug ("Direct reference is a label\n");
+ current_op->direct.label = token + 1;
+ save_input_line_pointer = input_line_pointer;
+ input_line_pointer = token + 1;
+ debug ("Current input_line_pointer: %s\n", input_line_pointer);
+ retval = expression (&current_op->direct.direct_expr);
+
+ debug ("Expression type: %d\n",
+ current_op->direct.direct_expr.X_op);
+ debug ("Expression addnum: %d\n",
+ current_op->direct.direct_expr.X_add_number);
+ debug ("Segment: %d\n", retval);
+
+ input_line_pointer = save_input_line_pointer;
+
+ if (current_op->direct.direct_expr.X_op == O_constant)
{
- int addr_insn = 0;
- /* Store instruction uses the second operand for the address mode. */
- if ((insn.tm->operand_types[1] & (Indirect | Direct)) == (Indirect | Direct))
- addr_insn = 1;
- if (insn.operand_type[addr_insn]->op_type & (AllReg))
- insn.addressing_mode = AM_Register;
- else if (insn.operand_type[addr_insn]->op_type & Direct)
- insn.addressing_mode = AM_Direct;
- else if (insn.operand_type[addr_insn]->op_type & Indirect)
- insn.addressing_mode = AM_Indirect;
- else
- insn.addressing_mode = AM_Immediate;
+ current_op->direct.address =
+ current_op->direct.direct_expr.X_add_number;
+ current_op->direct.resolved = 1;
}
}
else
{
- as_bad ("The %s operand doesn't match", ordinal_names[count]);
- return;
+ debug ("Direct reference is a number\n");
+ current_op->direct.address = atoi (token + 1);
+ current_op->direct.resolved = 1;
}
+ current_op->op_type = Direct;
}
- /* Now set the addressing mode for 3 operand instructions. */
- if ((insn.tm->operand_types[0] & op3T1) && (insn.tm->operand_types[1] & op3T2))
+ else if (*token == INDIRECT_REFERENCE)
{
- /* Set the addressing mode to the values used for 2 operand instructions in the
- G addressing field of the opcode. */
- char *p;
- switch (insn.operand_type[0]->op_type)
- {
- case Rn:
- case ARn:
- case DPReg:
- case OtherReg:
- if (insn.operand_type[1]->op_type & (AllReg))
- insn.addressing_mode = AM_Register;
- else if (insn.operand_type[1]->op_type & Indirect)
- insn.addressing_mode = AM_Direct;
- else
- {
- /* Shouldn't make it to this stage */
- as_bad ("Incompatible first and second operands in instruction");
- return;
- }
- break;
- case Indirect:
- if (insn.operand_type[1]->op_type & (AllReg))
- insn.addressing_mode = AM_Indirect;
- else if (insn.operand_type[1]->op_type & Indirect)
- insn.addressing_mode = AM_Immediate;
- else
- {
- /* Shouldn't make it to this stage */
- as_bad ("Incompatible first and second operands in instruction");
- return;
- }
- break;
- }
- /* Now make up the opcode for the 3 operand instructions. As in parallel
- instructions, there will be no unresolved values, so they can be fully formed
- and added to the frag table. */
- insn.opcode = insn.tm->base_opcode;
- if (insn.operand_type[0]->op_type & Indirect)
- {
- insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
- insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
- }
- else
- insn.opcode |= (insn.operand_type[0]->reg.opcode);
- if (insn.operand_type[1]->op_type & Indirect)
- {
- insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
- insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
- }
- else
- insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
- if (insn.operands == 3)
- insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
- insn.opcode |= insn.addressing_mode;
- p = frag_more (INSN_SIZE);
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- }
- else
- { /* Not a three operand instruction */
- char *p;
- int am_insn = -1;
- insn.opcode = insn.tm->base_opcode;
- /* Create frag for instruction - all instructions are 4 bytes long. */
- p = frag_more (INSN_SIZE);
- if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
+ /* Indirect reference operand. */
+ int found_ar = 0;
+ int found_disp = 0;
+ int ar_number = -1;
+ int disp_number = 0;
+ int buffer_posn = 1;
+ ind_addr_type *ind_addr_op;
+
+ debug ("Found indirect reference\n");
+ ind_buffer[0] = *token;
+
+ for (count = 1; count < strlen (token); count++)
{
- insn.opcode |= insn.addressing_mode;
- if (insn.addressing_mode == AM_Indirect)
- {
- /* Determine which operand gives the addressing mode */
- if (insn.operand_type[0]->op_type & Indirect)
- am_insn = 0;
- if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Indirect))
- am_insn = 1;
- insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
- insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
- insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
- if (insn.operands > 1)
- insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- }
- else if (insn.addressing_mode == AM_Register)
- {
- insn.opcode |= (insn.operand_type[0]->reg.opcode);
- if (insn.operands > 1)
- insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- }
- else if (insn.addressing_mode == AM_Direct)
+ /* Strip operand. */
+ ind_buffer[buffer_posn] = TOLOWER (*(token + count));
+
+ if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
+ && (*(token + count) == 'r' || *(token + count) == 'R'))
{
- if (insn.operand_type[0]->op_type & Direct)
- am_insn = 0;
- if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Direct))
- am_insn = 1;
- if (insn.operands > 1)
- insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
- if (insn.operand_type[am_insn]->direct.resolved == 1)
+ /* AR reference is found, so get its number and remove
+ it from the buffer so it can pass through hash_find(). */
+ if (found_ar)
{
- /* Resolved values can be placed straight into instruction word, and output */
- insn.opcode |= (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ as_bad ("More than one AR register found in indirect reference");
+ return NULL;
}
- else
- { /* Unresolved direct addressing mode instruction */
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[am_insn]->direct.direct_expr, 0, 0);
+ if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
+ {
+ as_bad ("Illegal AR register in indirect reference");
+ return NULL;
}
+ ar_number = *(token + count + 1) - '0';
+ found_ar = 1;
+ count++;
}
- else if (insn.addressing_mode == AM_Immediate)
+
+ if (*(token + count) == '(')
{
- if (insn.operand_type[0]->immediate.resolved == 1)
+ /* Parenthesis found, so check if a displacement value is
+ inside. If so, get the value and remove it from the
+ buffer. */
+ if (is_digit_char (*(token + count + 1)))
{
- char *keeploc;
- int size;
- if (insn.operands > 1)
- insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
- switch (insn.tm->imm_arg_type)
+ char disp[10];
+ int disp_posn = 0;
+
+ if (found_disp)
{
- case Imm_Float:
- debug ("Floating point first operand\n");
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- keeploc = input_line_pointer;
- input_line_pointer = insn.operand_type[0]->immediate.label;
- if (md_atof ('f', p + 2, &size) != 0)
- {
- as_bad ("invalid short form floating point immediate operand");
- return;
- }
- input_line_pointer = keeploc;
- break;
- case Imm_UInt:
- debug ("Unsigned int first operand\n");
- if (insn.operand_type[0]->immediate.decimal_found)
- as_warn ("rounding down first operand float to unsigned int");
- if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
- as_warn ("only lower 16-bits of first operand are used");
- insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- break;
- case Imm_SInt:
- debug ("Int first operand\n");
- if (insn.operand_type[0]->immediate.decimal_found)
- as_warn ("rounding down first operand float to signed int");
- if (insn.operand_type[0]->immediate.s_number < -32768 ||
- insn.operand_type[0]->immediate.s_number > 32767)
+ as_bad ("More than one displacement found in indirect reference");
+ return NULL;
+ }
+ count++;
+ while (*(token + count) != ')')
+ {
+ if (!is_digit_char (*(token + count)))
{
- as_bad ("first operand is too large for 16-bit signed int");
- return;
+ as_bad ("Invalid displacement in indirect reference");
+ return NULL;
}
- insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- break;
+ disp[disp_posn++] = *(token + (count++));
}
- }
- else
- { /* Unresolved immediate label */
- if (insn.operands > 1)
- insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
+ disp[disp_posn] = '\0';
+ disp_number = atoi (disp);
+ count--;
+ found_disp = 1;
}
}
+ buffer_posn++;
}
- else if (insn.tm->opcode_modifier == PCRel)
+
+ ind_buffer[buffer_posn] = '\0';
+ if (!found_ar)
+ {
+ as_bad ("AR register not found in indirect reference");
+ return NULL;
+ }
+
+ ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
+ if (ind_addr_op)
{
- /* Conditional Branch and Call instructions */
- if ((insn.tm->operand_types[0] & (AllReg | Disp)) == (AllReg | Disp))
+ debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
+ if (ind_addr_op->displacement == IMPLIED_DISP)
{
- if (insn.operand_type[0]->op_type & (AllReg))
- {
- insn.opcode |= (insn.operand_type[0]->reg.opcode);
- insn.opcode |= PC_Register;
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- }
- else
- {
- insn.opcode |= PC_Relative;
- if (insn.operand_type[0]->immediate.resolved == 1)
- {
- insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- }
- else
- {
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 1, 0);
- }
- }
+ found_disp = 1;
+ disp_number = 1;
}
- else if ((insn.tm->operand_types[0] & ARn) == ARn)
+ else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
{
- /* Decrement and Branch instructions */
- insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
- if (insn.operand_type[1]->op_type & (AllReg))
- {
- insn.opcode |= (insn.operand_type[1]->reg.opcode);
- insn.opcode |= PC_Register;
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- }
- else if (insn.operand_type[1]->immediate.resolved == 1)
- {
- if (insn.operand_type[0]->immediate.decimal_found)
- {
- as_bad ("first operand is floating point");
- return;
- }
- if (insn.operand_type[0]->immediate.s_number < -32768 ||
- insn.operand_type[0]->immediate.s_number > 32767)
- {
- as_bad ("first operand is too large for 16-bit signed int");
- return;
- }
- insn.opcode |= (insn.operand_type[1]->immediate.s_number);
- insn.opcode |= PC_Relative;
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- }
- else
- {
- insn.opcode |= PC_Relative;
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2, &insn.operand_type[1]->immediate.imm_expr, 1, 0);
- }
+ /* Maybe an implied displacement of 1 again. */
+ as_bad ("required displacement wasn't given in indirect reference");
+ return 0;
}
}
- else if (insn.tm->operand_types[0] == IVector)
+ else
{
- /* Trap instructions */
- if (insn.operand_type[0]->op_type & IVector)
- insn.opcode |= (insn.operand_type[0]->immediate.u_number);
- else
- { /* Shouldn't get here */
- as_bad ("interrupt vector for trap instruction out of range");
- return;
- }
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ as_bad ("illegal indirect reference");
+ return NULL;
}
- else if (insn.tm->opcode_modifier == StackOp || insn.tm->opcode_modifier == Rotate)
+
+ if (found_disp && (disp_number < 0 || disp_number > 255))
{
- /* Push, Pop and Rotate instructions */
- insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ as_bad ("displacement must be an unsigned 8-bit number");
+ return NULL;
}
- else if ((insn.tm->operand_types[0] & (Abs24 | Direct)) == (Abs24 | Direct))
+
+ current_op->indirect.mod = ind_addr_op->modfield;
+ current_op->indirect.disp = disp_number;
+ current_op->indirect.ARnum = ar_number;
+ current_op->op_type = Indirect;
+ }
+ else
+ {
+ reg *regop = (reg *) hash_find (reg_hash, token);
+
+ if (regop)
{
- /* LDP Instruction needs to be tested for before the next section */
- if (insn.operand_type[0]->op_type & Direct)
- {
- if (insn.operand_type[0]->direct.resolved == 1)
- {
- /* Direct addressing uses lower 8 bits of direct address */
- insn.opcode |= (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- }
- else
- {
- fixS *fix;
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
- /* Ensure that the assembler doesn't complain about fitting a 24-bit
- address into 8 bits. */
- fix->fx_no_overflow = 1;
- }
- }
+ debug ("Found register operand: %s\n", regop->name);
+ if (regop->regtype == REG_ARn)
+ current_op->op_type = ARn;
+ else if (regop->regtype == REG_Rn)
+ current_op->op_type = Rn;
+ else if (regop->regtype == REG_DP)
+ current_op->op_type = DPReg;
else
- {
- if (insn.operand_type[0]->immediate.resolved == 1)
- {
- /* Immediate addressing uses upper 8 bits of address */
- if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
- {
- as_bad ("LDP instruction needs a 24-bit operand");
- return;
- }
- insn.opcode |= ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- }
- else
- {
- fixS *fix;
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
- fix->fx_no_overflow = 1;
- }
- }
+ current_op->op_type = OtherReg;
+ current_op->reg.opcode = regop->opcode;
}
- else if (insn.tm->operand_types[0] & (Imm24))
+ else
{
- /* Unconditional Branch and Call instructions */
- if (insn.operand_type[0]->immediate.resolved == 1)
+ if (!is_digit_char (*token)
+ || *(token + 1) == 'x'
+ || strchr (token, 'h'))
{
- if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
- as_warn ("first operand is too large for a 24-bit displacement");
- insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ char *save_input_line_pointer;
+ segT retval;
+
+ debug ("Probably a label: %s\n", token);
+ current_op->immediate.label = malloc (strlen (token) + 1);
+ strcpy (current_op->immediate.label, token);
+ current_op->immediate.label[strlen (token)] = '\0';
+ save_input_line_pointer = input_line_pointer;
+ input_line_pointer = token;
+
+ debug ("Current input_line_pointer: %s\n", input_line_pointer);
+ retval = expression (&current_op->immediate.imm_expr);
+ debug ("Expression type: %d\n",
+ current_op->immediate.imm_expr.X_op);
+ debug ("Expression addnum: %d\n",
+ current_op->immediate.imm_expr.X_add_number);
+ debug ("Segment: %d\n", retval);
+ input_line_pointer = save_input_line_pointer;
+
+ if (current_op->immediate.imm_expr.X_op == O_constant)
+ {
+ current_op->immediate.s_number
+ = current_op->immediate.imm_expr.X_add_number;
+ current_op->immediate.u_number
+ = (unsigned int) current_op->immediate.imm_expr.X_add_number;
+ current_op->immediate.resolved = 1;
+ }
}
else
{
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
+ unsigned count;
+
+ debug ("Found a number or displacement\n");
+ for (count = 0; count < strlen (token); count++)
+ if (*(token + count) == '.')
+ current_op->immediate.decimal_found = 1;
+ current_op->immediate.label = malloc (strlen (token) + 1);
+ strcpy (current_op->immediate.label, token);
+ current_op->immediate.label[strlen (token)] = '\0';
+ current_op->immediate.f_number = (float) atof (token);
+ current_op->immediate.s_number = (int) atoi (token);
+ current_op->immediate.u_number = (unsigned int) atoi (token);
+ current_op->immediate.resolved = 1;
}
- }
- else if (insn.tm->operand_types[0] & NotReq)
- {
- /* Check for NOP instruction without arguments. */
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
- }
- else if (insn.tm->operands == 0)
- {
- /* Check for instructions without operands. */
- md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
+ if (current_op->immediate.u_number <= 31)
+ current_op->op_type |= IVector;
}
}
- debug ("Addressing mode: %08X\n", insn.addressing_mode);
- {
- unsigned int i;
- for (i = 0; i < insn.operands; i++)
- {
- if (insn.operand_type[i]->immediate.label)
- free (insn.operand_type[i]->immediate.label);
- free (insn.operand_type[i]);
- }
- }
- debug ("Final opcode: %08X\n", insn.opcode);
- debug ("\n");
+ return current_op;
}
-struct tic30_par_insn {
- partemplate *tm; /* Template of current parallel instruction */
- unsigned operands[2]; /* Number of given operands for each insn */
- /* Type of operand given in instruction */
+struct tic30_par_insn
+{
+ partemplate *tm; /* Template of current parallel instruction. */
+ unsigned operands[2]; /* Number of given operands for each insn. */
+ /* Type of operand given in instruction. */
operand *operand_type[2][MAX_OPERANDS];
int swap_operands; /* Whether to swap operands around. */
- unsigned p_field; /* Value of p field in multiply add/sub instructions */
- unsigned opcode; /* Final opcode */
+ unsigned p_field; /* Value of p field in multiply add/sub instructions. */
+ unsigned opcode; /* Final opcode. */
};
struct tic30_par_insn p_insn;
-int
+static int
tic30_parallel_insn (char *token)
{
static partemplate *p_opcode;
@@ -801,9 +670,11 @@ tic30_parallel_insn (char *token)
debug ("In tic30_parallel_insn with %s\n", token);
memset (&p_insn, '\0', sizeof (p_insn));
+
while (is_opcode_char (*current_posn))
current_posn++;
- { /* Find instruction */
+ {
+ /* Find instruction. */
save_char = *current_posn;
*current_posn = '\0';
p_opcode = (partemplate *) hash_find (parop_hash, token);
@@ -814,10 +685,8 @@ tic30_parallel_insn (char *token)
}
else
{
- char first_opcode[6] =
- {0};
- char second_opcode[6] =
- {0};
+ char first_opcode[6] = {0};
+ char second_opcode[6] = {0};
unsigned int i;
int current_opcode = -1;
int char_ptr = 0;
@@ -825,17 +694,20 @@ tic30_parallel_insn (char *token)
for (i = 0; i < strlen (token); i++)
{
char ch = *(token + i);
+
if (ch == '_' && current_opcode == -1)
{
current_opcode = 0;
continue;
}
+
if (ch == '_' && current_opcode == 0)
{
current_opcode = 1;
char_ptr = 0;
continue;
}
+
switch (current_opcode)
{
case 0:
@@ -846,10 +718,12 @@ tic30_parallel_insn (char *token)
break;
}
}
+
debug ("first_opcode = %s\n", first_opcode);
debug ("second_opcode = %s\n", second_opcode);
sprintf (token, "q_%s_%s", second_opcode, first_opcode);
p_opcode = (partemplate *) hash_find (parop_hash, token);
+
if (p_opcode)
{
debug ("Found instruction %s\n", p_opcode->name);
@@ -861,16 +735,21 @@ tic30_parallel_insn (char *token)
}
*current_posn = save_char;
}
- { /* Find operands */
+
+ {
+ /* Find operands. */
int paren_not_balanced;
int expecting_operand = 0;
int found_separator = 0;
+
do
{
- /* skip optional white space before operand */
- while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
+ /* Skip optional white space before operand. */
+ while (!is_operand_char (*current_posn)
+ && *current_posn != END_OF_INSN)
{
- if (!is_space_char (*current_posn) && *current_posn != PARALLEL_SEPARATOR)
+ if (!is_space_char (*current_posn)
+ && *current_posn != PARALLEL_SEPARATOR)
{
as_bad ("Invalid character %s before %s operand",
output_invalid (*current_posn),
@@ -881,8 +760,10 @@ tic30_parallel_insn (char *token)
found_separator = 1;
current_posn++;
}
- token_start = current_posn; /* after white space */
+
+ token_start = current_posn;
paren_not_balanced = 0;
+
while (paren_not_balanced || *current_posn != ',')
{
if (*current_posn == END_OF_INSN)
@@ -894,7 +775,7 @@ tic30_parallel_insn (char *token)
return 1;
}
else
- break; /* we are done */
+ break;
}
else if (*current_posn == PARALLEL_SEPARATOR)
{
@@ -902,21 +783,25 @@ tic30_parallel_insn (char *token)
current_posn--;
break;
}
- else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
+ else if (!is_operand_char (*current_posn)
+ && !is_space_char (*current_posn))
{
as_bad ("Invalid character %s in %s operand",
output_invalid (*current_posn),
ordinal_names[insn.operands]);
return 1;
}
+
if (*current_posn == '(')
++paren_not_balanced;
if (*current_posn == ')')
--paren_not_balanced;
current_posn++;
}
+
if (current_posn != token_start)
- { /* yes, we've read in another operand */
+ {
+ /* Yes, we've read in another operand. */
p_insn.operands[found_separator]++;
if (p_insn.operands[found_separator] > MAX_OPERANDS)
{
@@ -924,7 +809,8 @@ tic30_parallel_insn (char *token)
MAX_OPERANDS);
return 1;
}
- /* now parse operand adding info to 'insn' as we go along */
+
+ /* Now parse operand adding info to 'insn' as we go along. */
save_char = *current_posn;
*current_posn = '\0';
p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
@@ -946,19 +832,22 @@ tic30_parallel_insn (char *token)
return 1;
}
}
- /* now *current_posn must be either ',' or END_OF_INSN */
+
+ /* Now *current_posn must be either ',' or END_OF_INSN. */
if (*current_posn == ',')
{
if (*++current_posn == END_OF_INSN)
- { /* just skip it, if it's \n complain */
+ {
+ /* Just skip it, if it's \n complain. */
as_bad ("Expecting operand after ','; got nothing");
return 1;
}
expecting_operand = 1;
}
}
- while (*current_posn != END_OF_INSN); /* until we get end of insn */
+ while (*current_posn != END_OF_INSN);
}
+
if (p_insn.swap_operands)
{
int temp_num, i;
@@ -974,22 +863,28 @@ tic30_parallel_insn (char *token)
p_insn.operand_type[1][i] = temp_op;
}
}
+
if (p_insn.operands[0] != p_insn.tm->operands_1)
{
as_bad ("incorrect number of operands given in the first instruction");
return 1;
}
+
if (p_insn.operands[1] != p_insn.tm->operands_2)
{
as_bad ("incorrect number of operands given in the second instruction");
return 1;
}
+
debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
- { /* Now check if operands are correct */
+
+ {
+ /* Now check if operands are correct. */
int count;
int num_rn = 0;
int num_ind = 0;
+
for (count = 0; count < 2; count++)
{
unsigned int i;
@@ -998,64 +893,76 @@ tic30_parallel_insn (char *token)
if ((p_insn.operand_type[count][i]->op_type &
p_insn.tm->operand_types[count][i]) == 0)
{
- as_bad ("%s instruction, operand %d doesn't match", ordinal_names[count], i + 1);
+ as_bad ("%s instruction, operand %d doesn't match",
+ ordinal_names[count], i + 1);
return 1;
}
- /* Get number of R register and indirect reference contained within the first
- two operands of each instruction. This is required for the multiply
- parallel instructions which require two R registers and two indirect
- references, but not in any particular place. */
+
+ /* Get number of R register and indirect reference contained
+ within the first two operands of each instruction. This is
+ required for the multiply parallel instructions which require
+ two R registers and two indirect references, but not in any
+ particular place. */
if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
num_rn++;
- else if ((p_insn.operand_type[count][i]->op_type & Indirect) && i < 2)
+ else if ((p_insn.operand_type[count][i]->op_type & Indirect)
+ && i < 2)
num_ind++;
}
}
- if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn)) == (Indirect | Rn))
+
+ if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
+ == (Indirect | Rn))
{
- /* Check for the multiply instructions */
+ /* Check for the multiply instructions. */
if (num_rn != 2)
{
as_bad ("incorrect format for multiply parallel instruction");
return 1;
}
+
if (num_ind != 2)
- { /* Shouldn't get here */
+ {
+ /* Shouldn't get here. */
as_bad ("incorrect format for multiply parallel instruction");
return 1;
}
- if ((p_insn.operand_type[0][2]->reg.opcode != 0x00) &&
- (p_insn.operand_type[0][2]->reg.opcode != 0x01))
+
+ if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
+ && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
{
as_bad ("destination for multiply can only be R0 or R1");
return 1;
}
- if ((p_insn.operand_type[1][2]->reg.opcode != 0x02) &&
- (p_insn.operand_type[1][2]->reg.opcode != 0x03))
+
+ if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
+ && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
{
as_bad ("destination for add/subtract can only be R2 or R3");
return 1;
}
- /* Now determine the P field for the instruction */
+
+ /* Now determine the P field for the instruction. */
if (p_insn.operand_type[0][0]->op_type & Indirect)
{
if (p_insn.operand_type[0][1]->op_type & Indirect)
- p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn */
+ p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn. */
else if (p_insn.operand_type[1][0]->op_type & Indirect)
- p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn */
+ p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn. */
else
- p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind */
+ p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind. */
}
else
{
if (p_insn.operand_type[0][1]->op_type & Rn)
- p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind */
+ p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind. */
else if (p_insn.operand_type[1][0]->op_type & Indirect)
{
operand *temp;
- p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn */
- /* Need to swap the two multiply operands around so that everything is in
- its place for the opcode makeup ie so Ind * Rn, Ind +/- Rn */
+ p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn. */
+ /* Need to swap the two multiply operands around so that
+ everything is in its place for the opcode makeup.
+ ie so Ind * Rn, Ind +/- Rn. */
temp = p_insn.operand_type[0][0];
p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
p_insn.operand_type[0][1] = temp;
@@ -1063,7 +970,7 @@ tic30_parallel_insn (char *token)
else
{
operand *temp;
- p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind */
+ p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind. */
temp = p_insn.operand_type[0][0];
p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
p_insn.operand_type[0][1] = temp;
@@ -1071,476 +978,161 @@ tic30_parallel_insn (char *token)
}
}
}
+
debug ("P field: %08X\n", p_insn.p_field);
- /* Finalise opcode. This is easier for parallel instructions as they have to be
- fully resolved, there are no memory addresses allowed, except through indirect
- addressing, so there are no labels to resolve. */
- {
- p_insn.opcode = p_insn.tm->base_opcode;
- switch (p_insn.tm->oporder)
- {
- case OO_4op1:
- p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
- p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
- p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
- p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
- p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
- p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
- break;
- case OO_4op2:
- p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
- p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
- p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
- p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
- p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
- p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
- if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
- as_warn ("loading the same register in parallel operation");
- break;
- case OO_4op3:
- p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
- p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
- p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
- p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
- p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
- p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
- break;
- case OO_5op1:
- p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
- p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
- p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
- p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
- p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
- p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
- p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
- break;
- case OO_5op2:
- p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
- p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
- p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
- p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
- p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
- p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
- p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
- break;
- case OO_PField:
- p_insn.opcode |= p_insn.p_field;
- if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
- p_insn.opcode |= 0x00800000;
- if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
- p_insn.opcode |= 0x00400000;
- switch (p_insn.p_field)
- {
- case 0x00000000:
- p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
- p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
- p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
- p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
- p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
- p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
- break;
- case 0x01000000:
- p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
- p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
- p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
- p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
- p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
- p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
- break;
- case 0x02000000:
- p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
- p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
- p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
- p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
- p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
- p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
- break;
- case 0x03000000:
- p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
- p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
- p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
- p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
- p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
- p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
- break;
- }
- break;
- }
- } /* Opcode is finalised at this point for all parallel instructions. */
- { /* Output opcode */
- char *p;
- p = frag_more (INSN_SIZE);
- md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
- }
- {
- unsigned int i, j;
- for (i = 0; i < 2; i++)
- for (j = 0; j < p_insn.operands[i]; j++)
- free (p_insn.operand_type[i][j]);
- }
- debug ("Final opcode: %08X\n", p_insn.opcode);
- debug ("\n");
- return 1;
-}
-operand *
-tic30_operand (token)
- char *token;
-{
- unsigned int count;
- char ind_buffer[strlen (token)];
- operand *current_op;
+ /* Finalise opcode. This is easier for parallel instructions as they have
+ to be fully resolved, there are no memory addresses allowed, except
+ through indirect addressing, so there are no labels to resolve. */
+ p_insn.opcode = p_insn.tm->base_opcode;
- debug ("In tic30_operand with %s\n", token);
- current_op = (operand *) malloc (sizeof (operand));
- memset (current_op, '\0', sizeof (operand));
- if (*token == DIRECT_REFERENCE)
+ switch (p_insn.tm->oporder)
{
- char *token_posn = token + 1;
- int direct_label = 0;
- debug ("Found direct reference\n");
- while (*token_posn)
- {
- if (!is_digit_char (*token_posn))
- direct_label = 1;
- token_posn++;
- }
- if (direct_label)
- {
- char *save_input_line_pointer;
- segT retval;
- debug ("Direct reference is a label\n");
- current_op->direct.label = token + 1;
- save_input_line_pointer = input_line_pointer;
- input_line_pointer = token + 1;
- debug ("Current input_line_pointer: %s\n", input_line_pointer);
- retval = expression (&current_op->direct.direct_expr);
- debug ("Expression type: %d\n", current_op->direct.direct_expr.X_op);
- debug ("Expression addnum: %d\n", current_op->direct.direct_expr.X_add_number);
- debug ("Segment: %d\n", retval);
- input_line_pointer = save_input_line_pointer;
- if (current_op->direct.direct_expr.X_op == O_constant)
- {
- current_op->direct.address = current_op->direct.direct_expr.X_add_number;
- current_op->direct.resolved = 1;
- }
- }
- else
- {
- debug ("Direct reference is a number\n");
- current_op->direct.address = atoi (token + 1);
- current_op->direct.resolved = 1;
- }
- current_op->op_type = Direct;
- }
- else if (*token == INDIRECT_REFERENCE)
- { /* Indirect reference operand */
- int found_ar = 0;
- int found_disp = 0;
- int ar_number = -1;
- int disp_number = 0;
- int buffer_posn = 1;
- ind_addr_type *ind_addr_op;
- debug ("Found indirect reference\n");
- ind_buffer[0] = *token;
- for (count = 1; count < strlen (token); count++)
- { /* Strip operand */
- ind_buffer[buffer_posn] = TOLOWER (*(token + count));
- if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A') &&
- (*(token + count) == 'r' || *(token + count) == 'R'))
- {
- /* AR reference is found, so get its number and remove it from the buffer
- so it can pass through hash_find() */
- if (found_ar)
- {
- as_bad ("More than one AR register found in indirect reference");
- return NULL;
- }
- if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
- {
- as_bad ("Illegal AR register in indirect reference");
- return NULL;
- }
- ar_number = *(token + count + 1) - '0';
- found_ar = 1;
- count++;
- }
- if (*(token + count) == '(')
- {
- /* Parenthesis found, so check if a displacement value is inside. If so, get
- the value and remove it from the buffer. */
- if (is_digit_char (*(token + count + 1)))
- {
- char disp[10];
- int disp_posn = 0;
+ case OO_4op1:
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
+ break;
- if (found_disp)
- {
- as_bad ("More than one displacement found in indirect reference");
- return NULL;
- }
- count++;
- while (*(token + count) != ')')
- {
- if (!is_digit_char (*(token + count)))
- {
- as_bad ("Invalid displacement in indirect reference");
- return NULL;
- }
- disp[disp_posn++] = *(token + (count++));
- }
- disp[disp_posn] = '\0';
- disp_number = atoi (disp);
- count--;
- found_disp = 1;
- }
- }
- buffer_posn++;
- }
- ind_buffer[buffer_posn] = '\0';
- if (!found_ar)
- {
- as_bad ("AR register not found in indirect reference");
- return NULL;
- }
- ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
- if (ind_addr_op)
- {
- debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
- if (ind_addr_op->displacement == IMPLIED_DISP)
- {
- found_disp = 1;
- disp_number = 1;
- }
- else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
- {
- /* Maybe an implied displacement of 1 again */
- as_bad ("required displacement wasn't given in indirect reference");
- return 0;
- }
- }
- else
- {
- as_bad ("illegal indirect reference");
- return NULL;
- }
- if (found_disp && (disp_number < 0 || disp_number > 255))
- {
- as_bad ("displacement must be an unsigned 8-bit number");
- return NULL;
- }
- current_op->indirect.mod = ind_addr_op->modfield;
- current_op->indirect.disp = disp_number;
- current_op->indirect.ARnum = ar_number;
- current_op->op_type = Indirect;
- }
- else
- {
- reg *regop = (reg *) hash_find (reg_hash, token);
- if (regop)
- {
- debug ("Found register operand: %s\n", regop->name);
- if (regop->regtype == REG_ARn)
- current_op->op_type = ARn;
- else if (regop->regtype == REG_Rn)
- current_op->op_type = Rn;
- else if (regop->regtype == REG_DP)
- current_op->op_type = DPReg;
- else
- current_op->op_type = OtherReg;
- current_op->reg.opcode = regop->opcode;
- }
- else
- {
- if (!is_digit_char (*token) || *(token + 1) == 'x' || strchr (token, 'h'))
- {
- char *save_input_line_pointer;
- segT retval;
- debug ("Probably a label: %s\n", token);
- current_op->immediate.label = (char *) malloc (strlen (token) + 1);
- strcpy (current_op->immediate.label, token);
- current_op->immediate.label[strlen (token)] = '\0';
- save_input_line_pointer = input_line_pointer;
- input_line_pointer = token;
- debug ("Current input_line_pointer: %s\n", input_line_pointer);
- retval = expression (&current_op->immediate.imm_expr);
- debug ("Expression type: %d\n", current_op->immediate.imm_expr.X_op);
- debug ("Expression addnum: %d\n", current_op->immediate.imm_expr.X_add_number);
- debug ("Segment: %d\n", retval);
- input_line_pointer = save_input_line_pointer;
- if (current_op->immediate.imm_expr.X_op == O_constant)
- {
- current_op->immediate.s_number = current_op->immediate.imm_expr.X_add_number;
- current_op->immediate.u_number = (unsigned int) current_op->immediate.imm_expr.X_add_number;
- current_op->immediate.resolved = 1;
- }
- }
- else
- {
- unsigned count;
- debug ("Found a number or displacement\n");
- for (count = 0; count < strlen (token); count++)
- if (*(token + count) == '.')
- current_op->immediate.decimal_found = 1;
- current_op->immediate.label = (char *) malloc (strlen (token) + 1);
- strcpy (current_op->immediate.label, token);
- current_op->immediate.label[strlen (token)] = '\0';
- current_op->immediate.f_number = (float) atof (token);
- current_op->immediate.s_number = (int) atoi (token);
- current_op->immediate.u_number = (unsigned int) atoi (token);
- current_op->immediate.resolved = 1;
- }
- current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
- if (current_op->immediate.u_number <= 31)
- current_op->op_type |= IVector;
- }
- }
- return current_op;
-}
+ case OO_4op2:
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
+ if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
+ as_warn ("loading the same register in parallel operation");
+ break;
-/* next_line points to the next line after the current instruction (current_line).
- Search for the parallel bars, and if found, merge two lines into internal syntax
- for a parallel instruction:
- q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
- By this stage, all comments are scrubbed, and only the bare lines are given.
- */
+ case OO_4op3:
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
+ break;
-#define NONE 0
-#define START_OPCODE 1
-#define END_OPCODE 2
-#define START_OPERANDS 3
-#define END_OPERANDS 4
+ case OO_5op1:
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
+ p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
+ break;
-char *
-tic30_find_parallel_insn (current_line, next_line)
- char *current_line;
- char *next_line;
-{
- int found_parallel = 0;
- char first_opcode[256];
- char second_opcode[256];
- char first_operands[256];
- char second_operands[256];
- char *parallel_insn;
+ case OO_5op2:
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
+ p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
+ break;
- debug ("In tic30_find_parallel_insn()\n");
- while (!is_end_of_line[(unsigned char) *next_line])
- {
- if (*next_line == PARALLEL_SEPARATOR && *(next_line + 1) == PARALLEL_SEPARATOR)
+ case OO_PField:
+ p_insn.opcode |= p_insn.p_field;
+ if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
+ p_insn.opcode |= 0x00800000;
+ if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
+ p_insn.opcode |= 0x00400000;
+
+ switch (p_insn.p_field)
{
- found_parallel = 1;
- next_line++;
+ case 0x00000000:
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
+ break;
+ case 0x01000000:
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
+ break;
+ case 0x02000000:
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
+ break;
+ case 0x03000000:
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
break;
}
- next_line++;
+ break;
}
- if (!found_parallel)
- return NULL;
- debug ("Found a parallel instruction\n");
+
{
- int i;
- char *opcode, *operands, *line;
+ char *p;
- for (i = 0; i < 2; i++)
- {
- if (i == 0)
- {
- opcode = &first_opcode[0];
- operands = &first_operands[0];
- line = current_line;
- }
- else
- {
- opcode = &second_opcode[0];
- operands = &second_operands[0];
- line = next_line;
- }
- {
- int search_status = NONE;
- int char_ptr = 0;
- char c;
+ p = frag_more (INSN_SIZE);
+ md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
+ }
- while (!is_end_of_line[(unsigned char) (c = *line)])
- {
- if (is_opcode_char (c) && search_status == NONE)
- {
- opcode[char_ptr++] = TOLOWER (c);
- search_status = START_OPCODE;
- }
- else if (is_opcode_char (c) && search_status == START_OPCODE)
- {
- opcode[char_ptr++] = TOLOWER (c);
- }
- else if (!is_opcode_char (c) && search_status == START_OPCODE)
- {
- opcode[char_ptr] = '\0';
- char_ptr = 0;
- search_status = END_OPCODE;
- }
- else if (is_operand_char (c) && search_status == START_OPERANDS)
- {
- operands[char_ptr++] = c;
- }
- if (is_operand_char (c) && search_status == END_OPCODE)
- {
- operands[char_ptr++] = c;
- search_status = START_OPERANDS;
- }
- line++;
- }
- if (search_status != START_OPERANDS)
- return NULL;
- operands[char_ptr] = '\0';
- }
- }
+ {
+ unsigned int i, j;
+
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < p_insn.operands[i]; j++)
+ free (p_insn.operand_type[i][j]);
}
- parallel_insn = (char *) malloc (strlen (first_opcode) + strlen (first_operands) +
- strlen (second_opcode) + strlen (second_operands) + 8);
- sprintf (parallel_insn, "q_%s_%s %s | %s", first_opcode, second_opcode, first_operands, second_operands);
- debug ("parallel insn = %s\n", parallel_insn);
- return parallel_insn;
-}
-#undef NONE
-#undef START_OPCODE
-#undef END_OPCODE
-#undef START_OPERANDS
-#undef END_OPERANDS
+ debug ("Final opcode: %08X\n", p_insn.opcode);
+ debug ("\n");
+
+ return 1;
+}
/* In order to get gas to ignore any | chars at the start of a line,
this function returns true if a | is found in a line. */
int
-tic30_unrecognized_line (c)
- int c;
+tic30_unrecognized_line (int c)
{
debug ("In tc_unrecognized_line\n");
return (c == PARALLEL_SEPARATOR);
}
int
-md_estimate_size_before_relax (fragP, segment)
- fragS *fragP ATTRIBUTE_UNUSED;
- segT segment ATTRIBUTE_UNUSED;
+md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
+ segT segment ATTRIBUTE_UNUSED)
{
debug ("In md_estimate_size_before_relax()\n");
return 0;
}
void
-md_convert_frag (abfd, sec, fragP)
- bfd *abfd ATTRIBUTE_UNUSED;
- segT sec ATTRIBUTE_UNUSED;
- register fragS *fragP ATTRIBUTE_UNUSED;
+md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
+ segT sec ATTRIBUTE_UNUSED,
+ register fragS *fragP ATTRIBUTE_UNUSED)
{
debug ("In md_convert_frag()\n");
}
void
-md_apply_fix3 (fixP, valP, seg)
- fixS *fixP;
- valueT *valP;
- segT seg ATTRIBUTE_UNUSED;
+md_apply_fix3 (fixS *fixP,
+ valueT *valP,
+ segT seg ATTRIBUTE_UNUSED)
{
valueT value = *valP;
@@ -1567,35 +1159,31 @@ md_apply_fix3 (fixP, valP, seg)
}
int
-md_parse_option (c, arg)
- int c ATTRIBUTE_UNUSED;
- char *arg ATTRIBUTE_UNUSED;
+md_parse_option (int c ATTRIBUTE_UNUSED,
+ char *arg ATTRIBUTE_UNUSED)
{
debug ("In md_parse_option()\n");
return 0;
}
void
-md_show_usage (stream)
- FILE *stream ATTRIBUTE_UNUSED;
+md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
{
debug ("In md_show_usage()\n");
}
symbolS *
-md_undefined_symbol (name)
- char *name ATTRIBUTE_UNUSED;
+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
{
debug ("In md_undefined_symbol()\n");
return (symbolS *) 0;
}
valueT
-md_section_align (segment, size)
- segT segment;
- valueT size;
+md_section_align (segT segment, valueT size)
{
- debug ("In md_section_align() segment = %d and size = %d\n", segment, size);
+ debug ("In md_section_align() segment = %d and size = %d\n",
+ segment, size);
size = (size + 3) / 4;
size *= 4;
debug ("New size value = %d\n", size);
@@ -1603,17 +1191,17 @@ md_section_align (segment, size)
}
long
-md_pcrel_from (fixP)
- fixS *fixP;
+md_pcrel_from (fixS *fixP)
{
int offset;
debug ("In md_pcrel_from()\n");
debug ("fx_where = %d\n", fixP->fx_where);
debug ("fx_size = %d\n", fixP->fx_size);
- /* Find the opcode that represents the current instruction in the fr_literal
- storage area, and check bit 21. Bit 21 contains whether the current instruction
- is a delayed one or not, and then set the offset value appropriately. */
+ /* Find the opcode that represents the current instruction in the
+ fr_literal storage area, and check bit 21. Bit 21 contains whether the
+ current instruction is a delayed one or not, and then set the offset
+ value appropriately. */
if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
offset = 3;
else
@@ -1623,22 +1211,21 @@ md_pcrel_from (fixP)
displacement = Label - (PC + offset)
This function returns PC + offset where:
fx_where - fx_size = PC
- INSN_SIZE * offset = offset number of instructions
- */
+ INSN_SIZE * offset = offset number of instructions. */
return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
}
char *
-md_atof (what_statement_type, literalP, sizeP)
- int what_statement_type;
- char *literalP;
- int *sizeP;
+md_atof (int what_statement_type,
+ char *literalP,
+ int *sizeP)
{
int prec;
char *token;
char keepval;
unsigned long value;
float float_value;
+
debug ("In md_atof()\n");
debug ("precision = %c\n", what_statement_type);
debug ("literal = %s\n", literalP);
@@ -1650,12 +1237,14 @@ md_atof (what_statement_type, literalP, sizeP)
debug ("%c", *input_line_pointer);
input_line_pointer++;
}
+
keepval = *input_line_pointer;
*input_line_pointer = '\0';
debug ("\n");
float_value = (float) atof (token);
*input_line_pointer = keepval;
debug ("float_value = %f\n", float_value);
+
switch (what_statement_type)
{
case 'f':
@@ -1676,14 +1265,21 @@ md_atof (what_statement_type, literalP, sizeP)
*sizeP = 0;
return "Bad call to MD_ATOF()";
}
+
if (float_value == 0.0)
- {
- value = (prec == 2) ? 0x00008000L : 0x80000000L;
- }
+ value = (prec == 2) ? 0x00008000L : 0x80000000L;
else
{
unsigned long exp, sign, mant, tmsfloat;
- tmsfloat = *((long *) &float_value);
+ union
+ {
+ float f;
+ long l;
+ }
+ converter;
+
+ converter.f = float_value;
+ tmsfloat = converter.l;
sign = tmsfloat & 0x80000000;
mant = tmsfloat & 0x007FFFFF;
exp = tmsfloat & 0x7F800000;
@@ -1719,9 +1315,7 @@ md_atof (what_statement_type, literalP, sizeP)
long exp, mant;
if (tmsfloat == 0x80000000)
- {
- value = 0x8000;
- }
+ value = 0x8000;
else
{
value = 0;
@@ -1764,23 +1358,17 @@ md_atof (what_statement_type, literalP, sizeP)
}
void
-md_number_to_chars (buf, val, n)
- char *buf;
- valueT val;
- int n;
+md_number_to_chars (char *buf, valueT val, int n)
{
debug ("In md_number_to_chars()\n");
number_to_chars_bigendian (buf, val, n);
- /* number_to_chars_littleendian(buf,val,n); */
}
#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
arelent *
-tc_gen_reloc (section, fixP)
- asection *section ATTRIBUTE_UNUSED;
- fixS *fixP;
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
{
arelent *rel;
bfd_reloc_code_real_type code = 0;
@@ -1789,6 +1377,7 @@ tc_gen_reloc (section, fixP)
debug ("fixP.size = %d\n", fixP->fx_size);
debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
+
switch (F (fixP->fx_size, fixP->fx_pcrel))
{
MAP (1, 0, BFD_RELOC_TIC30_LDP);
@@ -1803,9 +1392,9 @@ tc_gen_reloc (section, fixP)
#undef MAP
#undef F
- rel = (arelent *) xmalloc (sizeof (arelent));
+ rel = xmalloc (sizeof (* rel));
assert (rel != 0);
- rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
*rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
rel->addend = 0;
@@ -1813,30 +1402,610 @@ tc_gen_reloc (section, fixP)
if (!rel->howto)
{
const char *name;
+
name = S_GET_NAME (fixP->fx_addsy);
if (name == NULL)
name = "<unknown>";
- as_fatal ("Cannot generate relocation type for symbol %s, code %s", name, bfd_get_reloc_code_name (code));
+ as_fatal ("Cannot generate relocation type for symbol %s, code %s",
+ name, bfd_get_reloc_code_name (code));
}
return rel;
}
void
-md_operand (expressionP)
- expressionS *expressionP ATTRIBUTE_UNUSED;
+md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
{
debug ("In md_operand()\n");
}
-char output_invalid_buf[8];
-
-char *
-output_invalid (c)
- char c;
+void
+md_assemble (char *line)
{
- if (ISPRINT (c))
- sprintf (output_invalid_buf, "'%c'", c);
+ template *opcode;
+ char *current_posn;
+ char *token_start;
+ char save_char;
+ unsigned int count;
+
+ debug ("In md_assemble() with argument %s\n", line);
+ memset (&insn, '\0', sizeof (insn));
+ if (found_parallel_insn)
+ {
+ debug ("Line is second part of parallel instruction\n\n");
+ found_parallel_insn = 0;
+ return;
+ }
+ if ((current_posn =
+ tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
+ current_posn = line;
else
- sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
- return output_invalid_buf;
+ found_parallel_insn = 1;
+
+ while (is_space_char (*current_posn))
+ current_posn++;
+
+ token_start = current_posn;
+
+ if (!is_opcode_char (*current_posn))
+ {
+ as_bad ("Invalid character %s in opcode",
+ output_invalid (*current_posn));
+ return;
+ }
+ /* Check if instruction is a parallel instruction
+ by seeing if the first character is a q. */
+ if (*token_start == 'q')
+ {
+ if (tic30_parallel_insn (token_start))
+ {
+ if (found_parallel_insn)
+ free (token_start);
+ return;
+ }
+ }
+ while (is_opcode_char (*current_posn))
+ current_posn++;
+ {
+ /* Find instruction. */
+ save_char = *current_posn;
+ *current_posn = '\0';
+ opcode = (template *) hash_find (op_hash, token_start);
+ if (opcode)
+ {
+ debug ("Found instruction %s\n", opcode->name);
+ insn.tm = opcode;
+ }
+ else
+ {
+ debug ("Didn't find insn\n");
+ as_bad ("Unknown TMS320C30 instruction: %s", token_start);
+ return;
+ }
+ *current_posn = save_char;
+ }
+
+ if (*current_posn != END_OF_INSN)
+ {
+ /* Find operands. */
+ int paren_not_balanced;
+ int expecting_operand = 0;
+ int this_operand;
+ do
+ {
+ /* Skip optional white space before operand. */
+ while (!is_operand_char (*current_posn)
+ && *current_posn != END_OF_INSN)
+ {
+ if (!is_space_char (*current_posn))
+ {
+ as_bad ("Invalid character %s before %s operand",
+ output_invalid (*current_posn),
+ ordinal_names[insn.operands]);
+ return;
+ }
+ current_posn++;
+ }
+ token_start = current_posn;
+ paren_not_balanced = 0;
+ while (paren_not_balanced || *current_posn != ',')
+ {
+ if (*current_posn == END_OF_INSN)
+ {
+ if (paren_not_balanced)
+ {
+ as_bad ("Unbalanced parenthesis in %s operand.",
+ ordinal_names[insn.operands]);
+ return;
+ }
+ else
+ break;
+ }
+ else if (!is_operand_char (*current_posn)
+ && !is_space_char (*current_posn))
+ {
+ as_bad ("Invalid character %s in %s operand",
+ output_invalid (*current_posn),
+ ordinal_names[insn.operands]);
+ return;
+ }
+ if (*current_posn == '(')
+ ++paren_not_balanced;
+ if (*current_posn == ')')
+ --paren_not_balanced;
+ current_posn++;
+ }
+ if (current_posn != token_start)
+ {
+ /* Yes, we've read in another operand. */
+ this_operand = insn.operands++;
+ if (insn.operands > MAX_OPERANDS)
+ {
+ as_bad ("Spurious operands; (%d operands/instruction max)",
+ MAX_OPERANDS);
+ return;
+ }
+
+ /* Now parse operand adding info to 'insn' as we go along. */
+ save_char = *current_posn;
+ *current_posn = '\0';
+ insn.operand_type[this_operand] = tic30_operand (token_start);
+ *current_posn = save_char;
+ if (insn.operand_type[this_operand] == NULL)
+ return;
+ }
+ else
+ {
+ if (expecting_operand)
+ {
+ as_bad ("Expecting operand after ','; got nothing");
+ return;
+ }
+ if (*current_posn == ',')
+ {
+ as_bad ("Expecting operand before ','; got nothing");
+ return;
+ }
+ }
+
+ /* Now *current_posn must be either ',' or END_OF_INSN. */
+ if (*current_posn == ',')
+ {
+ if (*++current_posn == END_OF_INSN)
+ {
+ /* Just skip it, if it's \n complain. */
+ as_bad ("Expecting operand after ','; got nothing");
+ return;
+ }
+ expecting_operand = 1;
+ }
+ }
+ while (*current_posn != END_OF_INSN);
+ }
+
+ debug ("Number of operands found: %d\n", insn.operands);
+
+ /* Check that number of operands is correct. */
+ if (insn.operands != insn.tm->operands)
+ {
+ unsigned int i;
+ unsigned int numops = insn.tm->operands;
+
+ /* If operands are not the same, then see if any of the operands are
+ not required. Then recheck with number of given operands. If they
+ are still not the same, then give an error, otherwise carry on. */
+ for (i = 0; i < insn.tm->operands; i++)
+ if (insn.tm->operand_types[i] & NotReq)
+ numops--;
+ if (insn.operands != numops)
+ {
+ as_bad ("Incorrect number of operands given");
+ return;
+ }
+ }
+ insn.addressing_mode = AM_NotReq;
+ for (count = 0; count < insn.operands; count++)
+ {
+ if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
+ {
+ debug ("Operand %d matches\n", count + 1);
+ /* If instruction has two operands and has an AddressMode
+ modifier then set addressing mode type for instruction. */
+ if (insn.tm->opcode_modifier == AddressMode)
+ {
+ int addr_insn = 0;
+ /* Store instruction uses the second
+ operand for the address mode. */
+ if ((insn.tm->operand_types[1] & (Indirect | Direct))
+ == (Indirect | Direct))
+ addr_insn = 1;
+
+ if (insn.operand_type[addr_insn]->op_type & (AllReg))
+ insn.addressing_mode = AM_Register;
+ else if (insn.operand_type[addr_insn]->op_type & Direct)
+ insn.addressing_mode = AM_Direct;
+ else if (insn.operand_type[addr_insn]->op_type & Indirect)
+ insn.addressing_mode = AM_Indirect;
+ else
+ insn.addressing_mode = AM_Immediate;
+ }
+ }
+ else
+ {
+ as_bad ("The %s operand doesn't match", ordinal_names[count]);
+ return;
+ }
+ }
+
+ /* Now set the addressing mode for 3 operand instructions. */
+ if ((insn.tm->operand_types[0] & op3T1)
+ && (insn.tm->operand_types[1] & op3T2))
+ {
+ /* Set the addressing mode to the values used for 2 operand
+ instructions in the G addressing field of the opcode. */
+ char *p;
+ switch (insn.operand_type[0]->op_type)
+ {
+ case Rn:
+ case ARn:
+ case DPReg:
+ case OtherReg:
+ if (insn.operand_type[1]->op_type & (AllReg))
+ insn.addressing_mode = AM_Register;
+ else if (insn.operand_type[1]->op_type & Indirect)
+ insn.addressing_mode = AM_Direct;
+ else
+ {
+ /* Shouldn't make it to this stage. */
+ as_bad ("Incompatible first and second operands in instruction");
+ return;
+ }
+ break;
+ case Indirect:
+ if (insn.operand_type[1]->op_type & (AllReg))
+ insn.addressing_mode = AM_Indirect;
+ else if (insn.operand_type[1]->op_type & Indirect)
+ insn.addressing_mode = AM_Immediate;
+ else
+ {
+ /* Shouldn't make it to this stage. */
+ as_bad ("Incompatible first and second operands in instruction");
+ return;
+ }
+ break;
+ }
+ /* Now make up the opcode for the 3 operand instructions. As in
+ parallel instructions, there will be no unresolved values, so they
+ can be fully formed and added to the frag table. */
+ insn.opcode = insn.tm->base_opcode;
+ if (insn.operand_type[0]->op_type & Indirect)
+ {
+ insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
+ insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
+ }
+ else
+ insn.opcode |= (insn.operand_type[0]->reg.opcode);
+
+ if (insn.operand_type[1]->op_type & Indirect)
+ {
+ insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
+ insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
+ }
+ else
+ insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
+
+ if (insn.operands == 3)
+ insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
+
+ insn.opcode |= insn.addressing_mode;
+ p = frag_more (INSN_SIZE);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ /* Not a three operand instruction. */
+ char *p;
+ int am_insn = -1;
+ insn.opcode = insn.tm->base_opcode;
+ /* Create frag for instruction - all instructions are 4 bytes long. */
+ p = frag_more (INSN_SIZE);
+ if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
+ {
+ insn.opcode |= insn.addressing_mode;
+ if (insn.addressing_mode == AM_Indirect)
+ {
+ /* Determine which operand gives the addressing mode. */
+ if (insn.operand_type[0]->op_type & Indirect)
+ am_insn = 0;
+ if ((insn.operands > 1)
+ && (insn.operand_type[1]->op_type & Indirect))
+ am_insn = 1;
+ insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
+ insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
+ insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.addressing_mode == AM_Register)
+ {
+ insn.opcode |= (insn.operand_type[0]->reg.opcode);
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.addressing_mode == AM_Direct)
+ {
+ if (insn.operand_type[0]->op_type & Direct)
+ am_insn = 0;
+ if ((insn.operands > 1)
+ && (insn.operand_type[1]->op_type & Direct))
+ am_insn = 1;
+ if (insn.operands > 1)
+ insn.opcode |=
+ (insn.operand_type[! am_insn]->reg.opcode << 16);
+ if (insn.operand_type[am_insn]->direct.resolved == 1)
+ {
+ /* Resolved values can be placed straight
+ into instruction word, and output. */
+ insn.opcode |=
+ (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ /* Unresolved direct addressing mode instruction. */
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
+ & insn.operand_type[am_insn]->direct.direct_expr,
+ 0, 0);
+ }
+ }
+ else if (insn.addressing_mode == AM_Immediate)
+ {
+ if (insn.operand_type[0]->immediate.resolved == 1)
+ {
+ char *keeploc;
+ int size;
+
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
+
+ switch (insn.tm->imm_arg_type)
+ {
+ case Imm_Float:
+ debug ("Floating point first operand\n");
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+
+ keeploc = input_line_pointer;
+ input_line_pointer =
+ insn.operand_type[0]->immediate.label;
+
+ if (md_atof ('f', p + 2, & size) != 0)
+ {
+ as_bad ("invalid short form floating point immediate operand");
+ return;
+ }
+
+ input_line_pointer = keeploc;
+ break;
+
+ case Imm_UInt:
+ debug ("Unsigned int first operand\n");
+ if (insn.operand_type[0]->immediate.decimal_found)
+ as_warn ("rounding down first operand float to unsigned int");
+ if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
+ as_warn ("only lower 16-bits of first operand are used");
+ insn.opcode |=
+ (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ break;
+
+ case Imm_SInt:
+ debug ("Int first operand\n");
+
+ if (insn.operand_type[0]->immediate.decimal_found)
+ as_warn ("rounding down first operand float to signed int");
+
+ if (insn.operand_type[0]->immediate.s_number < -32768 ||
+ insn.operand_type[0]->immediate.s_number > 32767)
+ {
+ as_bad ("first operand is too large for 16-bit signed int");
+ return;
+ }
+ insn.opcode |=
+ (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ break;
+ }
+ }
+ else
+ {
+ /* Unresolved immediate label. */
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
+ & insn.operand_type[0]->immediate.imm_expr,
+ 0, 0);
+ }
+ }
+ }
+ else if (insn.tm->opcode_modifier == PCRel)
+ {
+ /* Conditional Branch and Call instructions. */
+ if ((insn.tm->operand_types[0] & (AllReg | Disp))
+ == (AllReg | Disp))
+ {
+ if (insn.operand_type[0]->op_type & (AllReg))
+ {
+ insn.opcode |= (insn.operand_type[0]->reg.opcode);
+ insn.opcode |= PC_Register;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ insn.opcode |= PC_Relative;
+ if (insn.operand_type[0]->immediate.resolved == 1)
+ {
+ insn.opcode |=
+ (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
+ 2, & insn.operand_type[0]->immediate.imm_expr,
+ 1, 0);
+ }
+ }
+ }
+ else if ((insn.tm->operand_types[0] & ARn) == ARn)
+ {
+ /* Decrement and Branch instructions. */
+ insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
+ if (insn.operand_type[1]->op_type & (AllReg))
+ {
+ insn.opcode |= (insn.operand_type[1]->reg.opcode);
+ insn.opcode |= PC_Register;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.operand_type[1]->immediate.resolved == 1)
+ {
+ if (insn.operand_type[0]->immediate.decimal_found)
+ {
+ as_bad ("first operand is floating point");
+ return;
+ }
+ if (insn.operand_type[0]->immediate.s_number < -32768 ||
+ insn.operand_type[0]->immediate.s_number > 32767)
+ {
+ as_bad ("first operand is too large for 16-bit signed int");
+ return;
+ }
+ insn.opcode |= (insn.operand_type[1]->immediate.s_number);
+ insn.opcode |= PC_Relative;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ insn.opcode |= PC_Relative;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
+ & insn.operand_type[1]->immediate.imm_expr,
+ 1, 0);
+ }
+ }
+ }
+ else if (insn.tm->operand_types[0] == IVector)
+ {
+ /* Trap instructions. */
+ if (insn.operand_type[0]->op_type & IVector)
+ insn.opcode |= (insn.operand_type[0]->immediate.u_number);
+ else
+ {
+ /* Shouldn't get here. */
+ as_bad ("interrupt vector for trap instruction out of range");
+ return;
+ }
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.tm->opcode_modifier == StackOp
+ || insn.tm->opcode_modifier == Rotate)
+ {
+ /* Push, Pop and Rotate instructions. */
+ insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
+ == (Abs24 | Direct))
+ {
+ /* LDP Instruction needs to be tested
+ for before the next section. */
+ if (insn.operand_type[0]->op_type & Direct)
+ {
+ if (insn.operand_type[0]->direct.resolved == 1)
+ {
+ /* Direct addressing uses lower 8 bits of direct address. */
+ insn.opcode |=
+ (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ fixS *fix;
+
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
+ 1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
+ /* Ensure that the assembler doesn't complain
+ about fitting a 24-bit address into 8 bits. */
+ fix->fx_no_overflow = 1;
+ }
+ }
+ else
+ {
+ if (insn.operand_type[0]->immediate.resolved == 1)
+ {
+ /* Immediate addressing uses upper 8 bits of address. */
+ if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
+ {
+ as_bad ("LDP instruction needs a 24-bit operand");
+ return;
+ }
+ insn.opcode |=
+ ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ fixS *fix;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
+ 1, &insn.operand_type[0]->immediate.imm_expr,
+ 0, 0);
+ fix->fx_no_overflow = 1;
+ }
+ }
+ }
+ else if (insn.tm->operand_types[0] & (Imm24))
+ {
+ /* Unconditional Branch and Call instructions. */
+ if (insn.operand_type[0]->immediate.resolved == 1)
+ {
+ if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
+ as_warn ("first operand is too large for a 24-bit displacement");
+ insn.opcode |=
+ (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
+ & insn.operand_type[0]->immediate.imm_expr, 0, 0);
+ }
+ }
+ else if (insn.tm->operand_types[0] & NotReq)
+ /* Check for NOP instruction without arguments. */
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+
+ else if (insn.tm->operands == 0)
+ /* Check for instructions without operands. */
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ debug ("Addressing mode: %08X\n", insn.addressing_mode);
+ {
+ unsigned int i;
+
+ for (i = 0; i < insn.operands; i++)
+ {
+ if (insn.operand_type[i]->immediate.label)
+ free (insn.operand_type[i]->immediate.label);
+ free (insn.operand_type[i]);
+ }
+ }
+ debug ("Final opcode: %08X\n", insn.opcode);
+ debug ("\n");
}
+
diff --git a/gas/config/tc-tic30.h b/gas/config/tc-tic30.h
index 039671b..c6cb169 100644
--- a/gas/config/tc-tic30.h
+++ b/gas/config/tc-tic30.h
@@ -1,5 +1,5 @@
/* tc-tic30.h -- Header file for tc-tic30.c
- Copyright 1998, 2000, 2002 Free Software Foundation, Inc.
+ Copyright 1998, 2000, 2002, 2005 Free Software Foundation, Inc.
Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
This file is part of GAS, the GNU Assembler.
@@ -30,27 +30,23 @@
#define TARGET_ARCH bfd_arch_tic30
#define TARGET_BYTES_BIG_ENDIAN 1
-
#define WORKING_DOT_WORD
-
-char *output_invalid PARAMS ((int c));
-
-#define END_OF_INSN '\0'
-#define MAX_OPERANDS 6
-#define DIRECT_REFERENCE '@'
-#define INDIRECT_REFERENCE '*'
-#define PARALLEL_SEPARATOR '|'
-#define INSN_SIZE 4
+#define END_OF_INSN '\0'
+#define MAX_OPERANDS 6
+#define DIRECT_REFERENCE '@'
+#define INDIRECT_REFERENCE '*'
+#define PARALLEL_SEPARATOR '|'
+#define INSN_SIZE 4
/* Define this to 1 if you want the debug output to be on stdout,
otherwise stderr will be used. If stderr is used, there will be a
better synchronisation with the as_bad outputs, but you can't
capture the output. */
-#define USE_STDOUT 0
+#define USE_STDOUT 0
#define tc_unrecognized_line tic30_unrecognized_line
-extern int tic30_unrecognized_line PARAMS ((int));
+extern int tic30_unrecognized_line (int);
#define tc_aout_pre_write_hook {}