/* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
- Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1999-2021 Free Software Foundation, Inc.
Contributed by Timothy Wall (twall@cygnus.com)
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
+ the Free Software Foundation; either version 3, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to the Free
- Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
/* Texas Instruments TMS320C54X machine specific gas.
Written by Timothy Wall (twall@alum.mit.edu).
TI sets labels to be data type 4 (T_INT); GAS uses T_NULL.
COFF1 limits section names to 8 characters.
- Some of the default behavior changed from COFF1 to COFF2.
-*/
+ Some of the default behavior changed from COFF1 to COFF2. */
-#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
#include "as.h"
+#include <limits.h>
#include "safe-ctype.h"
#include "sb.h"
#include "macro.h"
#include "subsegs.h"
-#include "struc-symbol.h"
#include "opcode/tic54x.h"
#include "obj-coff.h"
#include <math.h>
-#define MAX_LINE 256 /* Lines longer than this are truncated by TI's asm. */
-const char comment_chars[] = ";";
-const char line_comment_chars[] = ";*#"; /* At column zero only. */
-const char line_separator_chars[] = ""; /* Not permitted. */
+static struct stag
+{
+ symbolS *sym; /* Symbol for this stag; value is offset. */
+ const char *name; /* Shortcut to symbol name. */
+ bfd_vma size; /* Size of struct/union. */
+ int current_bitfield_offset; /* Temporary for tracking fields. */
+ int is_union;
+ struct stag_field /* List of fields. */
+ {
+ const char *name;
+ bfd_vma offset; /* Of start of this field. */
+ int bitfield_offset; /* Of start of this field. */
+ struct stag *stag; /* If field is struct/union. */
+ struct stag_field *next;
+ } *field;
+ /* For nesting; used only in stag construction. */
+ struct stag *inner; /* Enclosed .struct. */
+ struct stag *outer; /* Enclosing .struct. */
+} *current_stag = NULL;
-/* Characters which indicate that this is a floating point constant. */
-const char FLT_CHARS[] = "fF";
+#define MAX_LINE 256 /* Lines longer than this are truncated by TI's asm. */
-/* Characters that can be used to separate mantissa from exp in FP
- nums. */
-const char EXP_CHARS[] = "eE";
+typedef struct _tic54x_insn
+{
+ const insn_template *tm; /* Opcode template. */
-/* Only word (et al.), align, or conditionals are allowed within
- .struct/.union. */
-#define ILLEGAL_WITHIN_STRUCT() \
- do \
- if (current_stag != NULL) \
- { \
- as_bad (_("pseudo-op illegal within .struct/.union")); \
- return; \
- } \
- while (0)
+ char mnemonic[MAX_LINE]; /* Opcode name/mnemonic. */
+ char parmnemonic[MAX_LINE]; /* 2nd mnemonic of parallel insn. */
-void
-md_show_usage (stream)
- FILE *stream;
-{
- fprintf (stream, _("C54x-specific command line options:\n"));
- fprintf (stream, _("-mfar-mode | -mf Use extended addressing\n"));
- fprintf (stream, _("-mcpu=<CPU version> Specify the CPU version\n"));
-#if 0
- fprintf (stream, _("-mcoff-version={0|1|2} Select COFF version\n"));
-#endif
- fprintf (stream, _("-merrors-to-file <filename>\n"));
- fprintf (stream, _("-me <filename> Redirect errors to a file\n"));
-}
+ int opcount;
+ struct opstruct
+ {
+ char buf[MAX_LINE];
+ enum optype type;
+ expressionS exp;
+ } operands[MAX_OPERANDS];
-const char *md_shortopts = "";
+ int paropcount;
+ struct opstruct paroperands[MAX_OPERANDS];
+
+ int is_lkaddr;
+ int lkoperand;
+ int words; /* Size of insn in 16-bit words. */
+ int using_default_dst; /* Do we need to explicitly set an
+ omitted OP_DST operand? */
+ struct
+ {
+ unsigned short word; /* Final encoded opcode data. */
+ int unresolved;
+ int r_nchars; /* Relocation size. */
+ bfd_reloc_code_real_type r_type; /* Relocation type. */
+ expressionS addr_expr; /* Storage for unresolved expressions. */
+ } opcode[3];
+} tic54x_insn;
enum cpu_version
{
far_mode /* >16-bit addresses. */
};
+static segT stag_saved_seg;
+static subsegT stag_saved_subseg;
+
+const char comment_chars[] = ";";
+const char line_comment_chars[] = ";*#"; /* At column zero only. */
+const char line_separator_chars[] = ""; /* Not permitted. */
+
+int emitting_long = 0;
+
+/* Characters which indicate that this is a floating point constant. */
+const char FLT_CHARS[] = "fF";
+
+/* Characters that can be used to separate mantissa from exp in FP
+ nums. */
+const char EXP_CHARS[] = "eE";
+
+const char *md_shortopts = "";
+
#define OPTION_ADDRESS_MODE (OPTION_MD_BASE)
#define OPTION_CPU_VERSION (OPTION_ADDRESS_MODE + 1)
#define OPTION_COFF_VERSION (OPTION_CPU_VERSION + 1)
struct option md_longopts[] =
{
- { "mfar-mode", no_argument, NULL, OPTION_ADDRESS_MODE },
- { "mf", no_argument, NULL, OPTION_ADDRESS_MODE },
- { "mcpu", required_argument, NULL, OPTION_CPU_VERSION },
-#if 0
- { "mcoff-version", required_argument, NULL, OPTION_COFF_VERSION },
-#endif
+ { "mfar-mode", no_argument, NULL, OPTION_ADDRESS_MODE },
+ { "mf", no_argument, NULL, OPTION_ADDRESS_MODE },
+ { "mcpu", required_argument, NULL, OPTION_CPU_VERSION },
{ "merrors-to-file", required_argument, NULL, OPTION_STDERR_TO_FILE },
- { "me", required_argument, NULL, OPTION_STDERR_TO_FILE },
- { NULL, no_argument, NULL, 0},
+ { "me", required_argument, NULL, OPTION_STDERR_TO_FILE },
+ { NULL, no_argument, NULL, 0},
};
size_t md_longopts_size = sizeof (md_longopts);
static int assembly_begun = 0;
/* Addressing mode is not entirely implemented; the latest rev of the Other
assembler doesn't seem to make any distinction whatsoever; all relocations
- are stored as extended relocatiosn. Older versions used REL16 vs RELEXT16,
+ are stored as extended relocations. Older versions used REL16 vs RELEXT16,
but now it seems all relocations are RELEXT16. We use all RELEXT16.
The cpu version is kind of a waste of time as well. There is one
/* This ensures that all new labels are unique. */
static int local_label_id;
-static struct hash_control *subsym_recurse_hash; /* Prevent infinite recurse. */
-static struct hash_control *math_hash; /* Built-in math functions. */
+static htab_t subsym_recurse_hash; /* Prevent infinite recurse. */
+static htab_t math_hash; /* Built-in math functions. */
/* Allow maximum levels of macro nesting; level 0 is the main substitution
symbol table. The other assembler only does 32 levels, so there! */
-static struct hash_control *subsym_hash[100];
+#define MAX_SUBSYM_HASH 100
+static htab_t subsym_hash[MAX_SUBSYM_HASH];
/* Keep track of local labels so we can substitute them before GAS sees them
since macros use their own 'namespace' for local labels, use a separate hash
We use our own macro nesting counter, since GAS overloads it when expanding
other things (like conditionals and repeat loops). */
static int macro_level = 0;
-static struct hash_control *local_label_hash[100];
+static htab_t local_label_hash[100];
/* Keep track of struct/union tags. */
-static struct hash_control *stag_hash;
-static struct hash_control *op_hash;
-static struct hash_control *parop_hash;
-static struct hash_control *reg_hash;
-static struct hash_control *mmreg_hash;
-static struct hash_control *cc_hash;
-static struct hash_control *cc2_hash;
-static struct hash_control *cc3_hash;
-static struct hash_control *sbit_hash;
-static struct hash_control *misc_symbol_hash;
-
-static char *subsym_substitute PARAMS ((char *line, int forced));
-static char *subsym_lookup PARAMS ((char *name, int nest_level));
-static void subsym_create_or_replace PARAMS ((char *name, char *value));
-static float math_ceil PARAMS ((float, float));
-static float math_cvi PARAMS ((float, float));
-static float math_floor PARAMS ((float, float));
-static float math_fmod PARAMS ((float, float));
-static float math_int PARAMS ((float, float));
-static float math_round PARAMS ((float, float));
-static float math_sgn PARAMS ((float, float));
-static float math_trunc PARAMS ((float, float));
-static float math_acos PARAMS ((float, float));
-static float math_asin PARAMS ((float, float));
-static float math_atan PARAMS ((float, float));
-static float math_atan2 PARAMS ((float, float));
-static float math_cosh PARAMS ((float, float));
-static float math_cos PARAMS ((float, float));
-static float math_cvf PARAMS ((float, float));
-static float math_exp PARAMS ((float, float));
-static float math_fabs PARAMS ((float, float));
-static float math_ldexp PARAMS ((float, float));
-static float math_log10 PARAMS ((float, float));
-static float math_log PARAMS ((float, float));
-static float math_max PARAMS ((float, float));
-static float math_pow PARAMS ((float, float));
-static float math_sin PARAMS ((float, float));
-static float math_sinh PARAMS ((float, float));
-static float math_sqrt PARAMS ((float, float));
-static float math_tan PARAMS ((float, float));
-static float math_tanh PARAMS ((float, float));
+static htab_t stag_hash;
+static htab_t op_hash;
+static htab_t parop_hash;
+static htab_t reg_hash;
+static htab_t mmreg_hash;
+static htab_t cc_hash;
+static htab_t cc2_hash;
+static htab_t cc3_hash;
+static htab_t sbit_hash;
+static htab_t misc_symbol_hash;
-static struct stag
-{
- symbolS *sym; /* Symbol for this stag; value is offset. */
- const char *name; /* Shortcut to symbol name. */
- bfd_vma size; /* Size of struct/union. */
- int current_bitfield_offset; /* Temporary for tracking fields. */
- int is_union;
- struct stag_field /* List of fields. */
- {
- const char *name;
- bfd_vma offset; /* Of start of this field. */
- int bitfield_offset; /* Of start of this field. */
- struct stag *stag; /* If field is struct/union. */
- struct stag_field *next;
- } *field;
- /* For nesting; used only in stag construction. */
- struct stag *inner; /* Enclosed .struct. */
- struct stag *outer; /* Enclosing .struct. */
-} *current_stag = NULL;
+/* Only word (et al.), align, or conditionals are allowed within
+ .struct/.union. */
+#define ILLEGAL_WITHIN_STRUCT() \
+ do \
+ if (current_stag != NULL) \
+ { \
+ as_bad (_("pseudo-op illegal within .struct/.union")); \
+ return; \
+ } \
+ while (0)
-static segT stag_saved_seg;
-static subsegT stag_saved_subseg;
-/* Output a single character (upper octect is zero). */
+static void subsym_create_or_replace (char *, char *);
+static char *subsym_lookup (char *, int);
+static char *subsym_substitute (char *, int);
+
+
+void
+md_show_usage (FILE *stream)
+{
+ fprintf (stream, _("C54x-specific command line options:\n"));
+ fprintf (stream, _("-mfar-mode | -mf Use extended addressing\n"));
+ fprintf (stream, _("-mcpu=<CPU version> Specify the CPU version\n"));
+ fprintf (stream, _("-merrors-to-file <filename>\n"));
+ fprintf (stream, _("-me <filename> Redirect errors to a file\n"));
+}
+
+/* Output a single character (upper octet is zero). */
static void
tic54x_emit_char (char c)
{
- expressionS exp;
+ expressionS expn;
- exp.X_op = O_constant;
- exp.X_add_number = c;
- emit_expr (&exp, 2);
+ expn.X_op = O_constant;
+ expn.X_add_number = c;
+ emit_expr (&expn, 2);
}
/* Walk backwards in the frag chain. */
expression. */
static char *
-parse_expression (char *str, expressionS * exp)
+parse_expression (char *str, expressionS *expn)
{
char *s;
char *tmp;
tmp = input_line_pointer; /* Save line pointer. */
input_line_pointer = str;
- expression (exp);
+ expression (expn);
s = input_line_pointer;
input_line_pointer = tmp; /* Restore line pointer. */
return s; /* Return pointer to where parsing stopped. */
int c;
char *name;
char *str;
- char *tmp;
int quoted = *input_line_pointer == '"';
ILLEGAL_WITHIN_STRUCT ();
str = input_line_pointer;
while ((c = *input_line_pointer) != ',')
{
- if (is_end_of_line[(int) *input_line_pointer])
+ if (is_end_of_line[(unsigned char) c])
break;
++input_line_pointer;
}
return;
}
- name = ++input_line_pointer;
- c = get_symbol_end (); /* Get terminator. */
+ ++input_line_pointer;
+ c = get_symbol_name (&name); /* Get terminator. */
if (!ISALPHA (*name))
{
- as_bad ("symbols assigned with .asg must begin with a letter");
+ as_bad (_("symbols assigned with .asg must begin with a letter"));
ignore_rest_of_line ();
return;
}
- tmp = xmalloc (strlen (str) + 1);
- strcpy (tmp, str);
- str = tmp;
- tmp = xmalloc (strlen (name) + 1);
- strcpy (tmp, name);
- name = tmp;
+ str = xstrdup (str);
+ name = xstrdup (name);
subsym_create_or_replace (name, str);
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
demand_empty_rest_of_line ();
}
ignore_rest_of_line ();
return;
}
- name = input_line_pointer;
- c = get_symbol_end (); /* Get terminator. */
- tmp = xmalloc (strlen (name) + 1);
- name = strcpy (tmp, name);
- *input_line_pointer = c;
+ c = get_symbol_name (&name); /* Get terminator. */
+ name = xstrdup (name);
+ (void) restore_line_pointer (c);
if (!ISALPHA (*name))
{
ignore_rest_of_line ();
return;
}
- symbolP = symbol_new (name, absolute_section,
- (valueT) value, &zero_address_frag);
+ symbolP = symbol_new (name, absolute_section, &zero_address_frag, value);
SF_SET_LOCAL (symbolP);
symbol_table_insert (symbolP);
But since there's not written rule as to when, don't even bother trying
to match their behavior. */
sprintf (valuestr, "%d", value);
- tmp = xmalloc (strlen (valuestr) + 1);
- strcpy (tmp, valuestr);
+ tmp = xstrdup (valuestr);
subsym_create_or_replace (name, tmp);
demand_empty_rest_of_line ();
current_seg = now_seg; /* Save current seg. */
current_subseg = now_subseg; /* Save current subseg. */
- name = input_line_pointer;
- c = get_symbol_end (); /* Get terminator. */
+ c = get_symbol_name (&name); /* Get terminator. */
+ if (c == '"')
+ c = * ++ input_line_pointer;
if (c != ',')
{
- as_bad (".bss size argument missing\n");
+ as_bad (_(".bss size argument missing\n"));
ignore_rest_of_line ();
return;
}
words = get_absolute_expression ();
if (words < 0)
{
- as_bad (".bss size %d < 0!", words);
+ as_bad (_(".bss size %d < 0!"), words);
ignore_rest_of_line ();
return;
}
symbolP = symbol_find_or_make (name);
if (S_GET_SEGMENT (symbolP) == bss_section)
- symbolP->sy_frag->fr_symbol = (symbolS *) NULL;
+ symbol_get_frag (symbolP)->fr_symbol = (symbolS *) NULL;
symbol_set_frag (symbolP, frag_now);
p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
}
if (block)
- bss_section->flags |= SEC_BLOCK;
+ bss_section->flags |= SEC_TIC54X_BLOCK;
subseg_set (current_seg, current_subseg); /* Restore current seg. */
demand_empty_rest_of_line ();
}
static void
-stag_add_field_symbols (struct stag *stag,
- const char *path,
- bfd_vma base_offset,
- symbolS *rootsym,
- const char *root_stag_name)
+stag_add_field_symbols (struct stag *stag,
+ const char *path,
+ bfd_vma base_offset,
+ symbolS *rootsym,
+ const char *root_stag_name)
{
- char prefix[strlen (path) + 2];
+ char * prefix;
struct stag_field *field = stag->field;
/* Construct a symbol for every field contained within this structure
including fields within structure fields. */
- strcpy (prefix, path);
- if (*path)
- strcat (prefix, ".");
+ prefix = concat (path, *path ? "." : "", NULL);
while (field != NULL)
{
- int len = strlen (prefix) + strlen (field->name) + 2;
- char *name = xmalloc (len);
- strcpy (name, prefix);
- strcat (name, field->name);
+ char *name = concat (prefix, field->name, NULL);
+ char *freename = name;
if (rootsym == NULL)
{
symbolS *sym;
- sym = symbol_new (name, absolute_section,
- (field->stag ? field->offset :
- (valueT) (base_offset + field->offset)),
- &zero_address_frag);
+ sym = symbol_new (name, absolute_section, &zero_address_frag,
+ (field->stag ? field->offset
+ : base_offset + field->offset));
SF_SET_LOCAL (sym);
symbol_table_insert (sym);
}
else
{
- char *replacement = xmalloc (strlen (name)
- + strlen (stag->name) + 2);
- strcpy (replacement, S_GET_NAME (rootsym));
- strcat (replacement, "+");
- strcat (replacement, root_stag_name);
- strcat (replacement, name + strlen (S_GET_NAME (rootsym)));
- hash_insert (subsym_hash[0], name, replacement);
+ char *replacement;
+
+ replacement = concat (S_GET_NAME (rootsym), "+", root_stag_name,
+ name + strlen (S_GET_NAME (rootsym)), NULL);
+ str_hash_insert (subsym_hash[0], name, replacement, 0);
+ freename = NULL;
}
/* Recurse if the field is a structure.
field->offset,
rootsym, root_stag_name);
field = field->next;
+ free (freename);
}
+ free (prefix);
}
/* Keep track of stag fields so that when structures are nested we can add the
complete dereferencing symbols to the symbol table. */
static void
-stag_add_field (struct stag *parent,
- const char *name,
- bfd_vma offset,
- struct stag *stag)
+stag_add_field (struct stag *parent,
+ const char *name,
+ bfd_vma offset,
+ struct stag *stag)
{
- struct stag_field *sfield = xmalloc (sizeof (struct stag_field));
+ struct stag_field *sfield = XCNEW (struct stag_field);
- memset (sfield, 0, sizeof (*sfield));
- sfield->name = strcpy (xmalloc (strlen (name) + 1), name);
+ sfield->name = xstrdup (name);
sfield->offset = offset;
sfield->bitfield_offset = parent->current_bitfield_offset;
sfield->stag = stag;
/* Only create a symbol for this field if the parent has no name. */
if (!strncmp (".fake", parent->name, 5))
{
- symbolS *sym = symbol_new (name, absolute_section,
- (valueT) offset, &zero_address_frag);
+ symbolS *sym = symbol_new (name, absolute_section, &zero_address_frag,
+ offset);
SF_SET_LOCAL (sym);
symbol_table_insert (sym);
}
{
/* Offset is ignored in inner structs. */
SKIP_WHITESPACE ();
- if (!is_end_of_line[(int) *input_line_pointer])
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
start_offset = get_absolute_expression ();
else
start_offset = 0;
if (current_stag)
{
/* Nesting, link to outer one. */
- current_stag->inner = (struct stag *) xmalloc (sizeof (struct stag));
- memset (current_stag->inner, 0, sizeof (struct stag));
+ current_stag->inner = XCNEW (struct stag);
current_stag->inner->outer = current_stag;
current_stag = current_stag->inner;
if (start_offset)
}
else
{
- current_stag = (struct stag *) xmalloc (sizeof (struct stag));
- memset (current_stag, 0, sizeof (struct stag));
+ current_stag = XCNEW (struct stag);
abs_section_offset = start_offset;
}
current_stag->is_union = is_union;
char fake[] = ".fake_stagNNNNNNN";
sprintf (fake, ".fake_stag%d", struct_count++);
current_stag->sym = symbol_new (fake, absolute_section,
- (valueT) abs_section_offset,
- &zero_address_frag);
+ &zero_address_frag,
+ abs_section_offset);
}
else
{
- char label[strlen (S_GET_NAME (line_label)) + 1];
- strcpy (label, S_GET_NAME (line_label));
- current_stag->sym = symbol_new (label, absolute_section,
- (valueT) abs_section_offset,
- &zero_address_frag);
+ char * label = xstrdup (S_GET_NAME (line_label));
+ current_stag->sym = symbol_new (label,
+ absolute_section,
+ &zero_address_frag,
+ abs_section_offset);
+ free (label);
}
current_stag->name = S_GET_NAME (current_stag->sym);
SF_SET_LOCAL (current_stag->sym);
/* Nested .structs don't get put in the stag table. */
if (current_stag->outer == NULL)
{
- hash_insert (stag_hash, current_stag->name, current_stag);
+ str_hash_insert (stag_hash, current_stag->name, current_stag, 0);
stag_add_field_symbols (current_stag, path,
S_GET_VALUE (current_stag->sym),
NULL, NULL);
static void
tic54x_tag (int ignore ATTRIBUTE_UNUSED)
{
- char *name = input_line_pointer;
- int c = get_symbol_end ();
- struct stag *stag = (struct stag *) hash_find (stag_hash, name);
+ char *name;
+ int c = get_symbol_name (&name);
+ struct stag *stag = (struct stag *) str_hash_find (stag_hash, name);
if (!stag)
{
}
else
{
- char label[strlen (S_GET_NAME (line_label)) + 1];
+ char * label;
- strcpy (label, S_GET_NAME (line_label));
+ label = xstrdup (S_GET_NAME (line_label));
if (current_stag != NULL)
stag_add_field (current_stag, label,
abs_section_offset - S_GET_VALUE (current_stag->sym),
else
{
symbolS *sym = symbol_find (label);
+
if (!sym)
{
as_bad (_(".tag target '%s' undefined"), label);
ignore_rest_of_line ();
+ free (label);
return;
}
stag_add_field_symbols (stag, S_GET_NAME (sym),
S_GET_VALUE (stag->sym), sym, stag->name);
}
+ free (label);
}
/* Bump by the struct size, but only if we're within a .struct section. */
if (current_stag != NULL && !current_stag->is_union)
abs_section_offset += stag->size;
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
demand_empty_rest_of_line ();
line_label = NULL;
}
int longword_align = 0;
SKIP_WHITESPACE ();
- if (!is_end_of_line[(int) *input_line_pointer])
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
count = get_absolute_expression ();
switch (type)
new_bitfield_offset = count - 16;
}
else
- {
- new_bitfield_offset = count;
- }
+ new_bitfield_offset = count;
}
else
{
{
static int fieldno = 0;
char fake[] = ".fake_fieldNNNNN";
+
sprintf (fake, ".fake_field%d", fieldno++);
stag_add_field (current_stag, fake,
abs_section_offset - S_GET_VALUE (current_stag->sym),
}
else
{
- char label[strlen (S_GET_NAME (line_label) + 1)];
- strcpy (label, S_GET_NAME (line_label));
+ char * label;
+
+ label = xstrdup (S_GET_NAME (line_label));
stag_add_field (current_stag, label,
abs_section_offset - S_GET_VALUE (current_stag->sym),
NULL);
+ free (label);
}
if (current_stag->is_union)
/* Handle .byte, .word. .int, .long and all variants. */
-int emitting_long = 0;
static void
tic54x_cons (int type)
{
- register unsigned int c;
+ unsigned int c;
int octets;
/* If we're within a .struct construct, don't actually allocate space. */
}
else
{
- expressionS exp;
+ expressionS expn;
- input_line_pointer = parse_expression (input_line_pointer, &exp);
- if (exp.X_op == O_constant)
+ input_line_pointer = parse_expression (input_line_pointer, &expn);
+ if (expn.X_op == O_constant)
{
- offsetT value = exp.X_add_number;
+ offsetT value = expn.X_add_number;
/* Truncate overflows. */
switch (octets)
{
case 1:
if ((value > 0 && value > 0xFF)
|| (value < 0 && value < - 0x100))
- as_warn ("Overflow in expression, truncated to 8 bits");
+ as_warn (_("Overflow in expression, truncated to 8 bits"));
break;
case 2:
if ((value > 0 && value > 0xFFFF)
|| (value < 0 && value < - 0x10000))
- as_warn ("Overflow in expression, truncated to 16 bits");
+ as_warn (_("Overflow in expression, truncated to 16 bits"));
break;
}
}
- if (exp.X_op != O_constant && octets < 2)
+ if (expn.X_op != O_constant && octets < 2)
{
/* Disallow .byte with a non constant expression that will
require relocation. */
return;
}
- if (exp.X_op != O_constant
+ if (expn.X_op != O_constant
&& amode == c_mode
&& octets == 4)
{
/* FIXME -- at one point TI tools used to output REL16
relocations, but I don't think the latest tools do at all
The current tools output extended relocations regardless of
- the addresing mode (I actually think that ".c_mode" is
+ the addressing mode (I actually think that ".c_mode" is
totally ignored in the latest tools). */
amode = far_mode;
emitting_long = 1;
- emit_expr (&exp, 4);
+ emit_expr (&expn, 4);
emitting_long = 0;
amode = c_mode;
}
else
{
emitting_long = octets == 4;
- emit_expr (&exp, (octets == 1) ? 2 : octets);
+ emit_expr (&expn, (octets == 1) ? 2 : octets);
emitting_long = 0;
}
}
do
{
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
symbolP = symbol_find_or_make (name);
+ c = restore_line_pointer (c);
- *input_line_pointer = c;
S_SET_STORAGE_CLASS (symbolP, C_EXT);
if (c == ',')
{
input_line_pointer++;
- if (is_end_of_line[(int) *input_line_pointer])
+ if (is_end_of_line[(unsigned char) *input_line_pointer])
c = *input_line_pointer;
}
}
/* Remove the symbol from the local label hash lookup. */
-static void
-tic54x_remove_local_label (const char *key,
- PTR value ATTRIBUTE_UNUSED)
+static int
+tic54x_remove_local_label (void **slot, void *arg ATTRIBUTE_UNUSED)
{
- PTR *elem = hash_delete (local_label_hash[macro_level], key);
+ string_tuple_t *tuple = *((string_tuple_t **) slot);
+ void *elem = str_hash_find (local_label_hash[macro_level], tuple->key);
+ str_hash_delete (local_label_hash[macro_level], tuple->key);
free (elem);
+ return 0;
}
/* Reset all local labels. */
static void
tic54x_clear_local_labels (int ignored ATTRIBUTE_UNUSED)
{
- hash_traverse (local_label_hash[macro_level], tic54x_remove_local_label);
+ htab_traverse (local_label_hash[macro_level], tic54x_remove_local_label, NULL);
}
/* .text
{
char *name = NULL;
int len;
+ /* Make sure all named initialized sections flagged properly. If we
+ encounter instructions, we'll flag it with SEC_CODE as well. */
+ const char *flags = ",\"w\"\n";
+
/* If there are quotes, remove them. */
if (*input_line_pointer == '"')
{
name = demand_copy_C_string (&len);
demand_empty_rest_of_line ();
- name = strcpy (xmalloc (len + 10), name);
+ name = concat (name, flags, (char *) NULL);
}
else
{
int c;
- name = input_line_pointer;
- c = get_symbol_end ();
- len = strlen(name);
- name = strcpy (xmalloc (len + 10), name);
- *input_line_pointer = c;
+
+ c = get_symbol_name (&name);
+ name = concat (name, flags, (char *) NULL);
+ (void) restore_line_pointer (c);
demand_empty_rest_of_line ();
}
- /* Make sure all named initialized sections flagged properly. If we
- encounter instructions, we'll flag it with SEC_CODE as well. */
- strcat (name, ",\"w\"\n");
+
input_scrub_insert_line (name);
obj_coff_section (0);
static void
tic54x_space (int arg)
{
- expressionS exp;
+ expressionS expn;
char *p = 0;
int octets = 0;
long words;
#endif
/* Read the bit count. */
- expression (&exp);
+ expression (&expn);
/* Some expressions are unresolvable until later in the assembly pass;
postpone until relaxation/fixup. we also have to postpone if a previous
partial allocation has not been completed yet. */
- if (exp.X_op != O_constant || frag_bit_offset (frag_now, now_seg) == -1)
+ if (expn.X_op != O_constant || frag_bit_offset (frag_now, now_seg) == -1)
{
- struct bit_info *bi = xmalloc (sizeof (struct bit_info));
- char *p;
+ struct bit_info *bi = XNEW (struct bit_info);
bi->seg = now_seg;
bi->type = bes;
bi->sym = label;
p = frag_var (rs_machine_dependent,
65536 * 2, 1, (relax_substateT) 0,
- make_expr_symbol (&exp), (offsetT) 0,
+ make_expr_symbol (&expn), (offsetT) 0,
(char *) bi);
if (p)
*p = 0;
if (bit_offset != 0 && bit_offset < 16)
{
int spare_bits = bits_per_byte - bit_offset;
- if (spare_bits >= exp.X_add_number)
+
+ if (spare_bits >= expn.X_add_number)
{
/* Don't have to do anything; sufficient bits have already been
allocated; just point the label to the right place. */
S_SET_VALUE (label, frag_now_fix () - 1);
label = NULL;
}
- frag_now->tc_frag_data += exp.X_add_number;
+ frag_now->tc_frag_data += expn.X_add_number;
goto getout;
}
- exp.X_add_number -= spare_bits;
+ expn.X_add_number -= spare_bits;
/* Set the label to point to the first word allocated, which in this
case is the previous word, which was only partially filled. */
if (!bes && label != NULL)
}
}
/* Convert bits to bytes/words and octets, rounding up. */
- words = ((exp.X_add_number + bits_per_byte - 1) / bits_per_byte);
+ words = ((expn.X_add_number + bits_per_byte - 1) / bits_per_byte);
/* How many do we have left over? */
- bit_offset = exp.X_add_number % bits_per_byte;
+ bit_offset = expn.X_add_number % bits_per_byte;
octets = words * OCTETS_PER_BYTE;
if (octets < 0)
{
/* [symbol] .usect "section-name", size-in-words
[, [blocking-flag] [, alignment-flag]]
- Unitialized section.
+ Uninitialized section.
Non-zero blocking means that if the section would cross a page (128-word)
boundary, it will be page-aligned.
Non-zero alignment aligns on a longword boundary.
current_seg = now_seg; /* Save current seg. */
current_subseg = now_subseg; /* Save current subseg. */
- if (*input_line_pointer == '"')
- input_line_pointer++;
- section_name = input_line_pointer;
- c = get_symbol_end (); /* Get terminator. */
- input_line_pointer++; /* Skip null symbol terminator. */
- name = xmalloc (input_line_pointer - section_name + 1);
- strcpy (name, section_name);
-
- if (*input_line_pointer == ',')
+ c = get_symbol_name (§ion_name); /* Get terminator. */
+ name = xstrdup (section_name);
+ c = restore_line_pointer (c);
+
+ if (c == ',')
++input_line_pointer;
- else if (c != ',')
+ else
{
as_bad (_("Missing size argument"));
ignore_rest_of_line ();
blocking_flag = alignment_flag = 0;
seg = subseg_new (name, 0);
- flags = bfd_get_section_flags (stdoutput, seg) | SEC_ALLOC;
+ flags = bfd_section_flags (seg) | SEC_ALLOC;
if (alignment_flag)
{
*p = 0;
if (blocking_flag)
- flags |= SEC_BLOCK;
+ flags |= SEC_TIC54X_BLOCK;
- if (!bfd_set_section_flags (stdoutput, seg, flags))
- as_warn ("Error setting flags for \"%s\": %s", name,
+ if (!bfd_set_section_flags (seg, flags))
+ as_warn (_("Error setting flags for \"%s\": %s"), name,
bfd_errmsg (bfd_get_error ()));
subseg_set (current_seg, current_subseg); /* Restore current seg. */
if (version == V545LP || version == V546LP)
{
symbolS *symbolP = symbol_new ("__allow_lp", absolute_section,
- (valueT) 1, &zero_address_frag);
+ &zero_address_frag, 1);
SF_SET_LOCAL (symbolP);
symbol_table_insert (symbolP);
}
SKIP_WHITESPACE ();
ver = input_line_pointer;
- while (!is_end_of_line[(int) *input_line_pointer])
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
++input_line_pointer;
c = *input_line_pointer;
*input_line_pointer = 0;
/* The argument is capitalized if it should be zero-terminated
's' is normal string with upper 8-bits zero-filled, 'p' is packed.
- Code copied from stringer, and slightly modified so that strings are packed
+ Code copied from stringer, and slightly modified so that strings are packed
and encoded into the correct octets. */
static void
tic54x_stringer (int type)
{
- register unsigned int c;
- char *start;
+ unsigned int c;
int append_zero = type == 'S' || type == 'P';
int packed = type == 'p' || type == 'P';
int last_char = -1; /* Packed strings need two bytes at a time to encode. */
}
case '\"':
++input_line_pointer; /* -> 1st char of string. */
- start = input_line_pointer;
while (is_a_char (c = next_char_of_string ()))
{
if (!packed)
/* Only ".align" with no argument is allowed within .struct/.union. */
int count = arg;
- if (!is_end_of_line[(int) *input_line_pointer])
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
{
if (arg == 2)
as_warn (_("Argument to .even ignored"));
s_align_bytes (count << 1);
}
-/* Initialize multiple-bit fields withing a single word of memory. */
+/* Initialize multiple-bit fields within a single word of memory. */
static void
tic54x_field (int ignore ATTRIBUTE_UNUSED)
{
- expressionS exp;
+ expressionS expn;
int size = 16;
char *p;
valueT value;
return;
}
- input_line_pointer = parse_expression (input_line_pointer, &exp);
+ input_line_pointer = parse_expression (input_line_pointer, &expn);
if (*input_line_pointer == ',')
{
}
/* Truncate values to the field width. */
- if (exp.X_op != O_constant)
+ if (expn.X_op != O_constant)
{
/* If the expression value is relocatable, the field size *must*
be 16. */
}
frag_now->tc_frag_data = 0;
- emit_expr (&exp, 2);
+ emit_expr (&expn, 2);
}
else
{
unsigned long fmask = (size == 32) ? 0xFFFFFFFF : (1ul << size) - 1;
- value = exp.X_add_number;
- exp.X_add_number &= fmask;
- if (value != (valueT) exp.X_add_number)
+
+ value = expn.X_add_number;
+ expn.X_add_number &= fmask;
+ if (value != (valueT) expn.X_add_number)
as_warn (_("field value truncated"));
- value = exp.X_add_number;
+ value = expn.X_add_number;
/* Bits are stored MS first. */
while (size >= 16)
{
if (size > 0)
{
int bit_offset = frag_bit_offset (frag_now, now_seg);
+
fragS *alloc_frag = bit_offset_frag (frag_now, now_seg);
if (bit_offset == -1)
{
- struct bit_info *bi = xmalloc (sizeof (struct bit_info));
+ struct bit_info *bi = XNEW (struct bit_info);
/* We don't know the previous offset at this time, so store the
info we need and figure it out later. */
expressionS size_exp;
+
size_exp.X_op = O_constant;
size_exp.X_add_number = size;
bi->seg = now_seg;
{
char *section_name = ++input_line_pointer;
char *name;
+
while (is_a_char (next_char_of_string ()))
;
know (input_line_pointer[-1] == '\"');
input_line_pointer[-1] = 0;
- name = xmalloc (input_line_pointer - section_name + 1);
- strcpy (name, section_name);
+ name = xstrdup (section_name);
seg = bfd_get_section_by_name (stdoutput, name);
if (seg == NULL)
{
if (!tic54x_initialized_section (seg))
{
- as_bad (_("Current section is unitialized, "
+ as_bad (_("Current section is uninitialized, "
"section name required for .clink"));
ignore_rest_of_line ();
return;
}
}
- seg->flags |= SEC_CLINK;
+ seg->flags |= SEC_TIC54X_CLINK;
demand_empty_rest_of_line ();
}
set to "." instead. */
static void
-tic54x_set_default_include (int dot)
+tic54x_set_default_include (void)
{
- char *dir = ".";
- char *tmp = NULL;
+ char *dir, *tmp = NULL;
+ const char *curfile;
+ unsigned lineno;
- if (!dot)
- {
- char *curfile;
- unsigned lineno;
-
- as_where (&curfile, &lineno);
- dir = strcpy (xmalloc (strlen (curfile) + 1), curfile);
- tmp = strrchr (dir, '/');
- }
+ curfile = as_where (&lineno);
+ dir = xstrdup (curfile);
+ tmp = strrchr (dir, '/');
if (tmp != NULL)
{
int len;
+
*tmp = '\0';
len = strlen (dir);
if (include_dir_count == 0)
{
- include_dirs = (char **) xmalloc (sizeof (*include_dirs));
+ include_dirs = XNEWVEC (const char *, 1);
include_dir_count = 1;
}
include_dirs[0] = dir;
else
{
filename = input_line_pointer;
- while (!is_end_of_line[(int) *input_line_pointer])
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
++input_line_pointer;
c = *input_line_pointer;
*input_line_pointer = '\0';
- filename = strcpy (xmalloc (strlen (filename) + 1), filename);
+ filename = xstrdup (filename);
*input_line_pointer = c;
demand_empty_rest_of_line ();
}
and a .newblock.
The included file will be inserted before the newblock, so that the
newblock is executed after the included file is processed. */
- input = xmalloc (sizeof (newblock) + strlen (filename) + 4);
- sprintf (input, "\"%s\"\n%s", filename, newblock);
+ input = concat ("\"", filename, "\"\n", newblock, (char *) NULL);
input_scrub_insert_line (input);
tic54x_clear_local_labels (0);
- tic54x_set_default_include (0);
+ tic54x_set_default_include ();
s_include (0);
}
else
{
msg = input_line_pointer;
- while (!is_end_of_line[(int) *input_line_pointer])
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
++input_line_pointer;
c = *input_line_pointer;
*input_line_pointer = 0;
- msg = strcpy (xmalloc (strlen (msg) + 1), msg);
+ msg = xstrdup (msg);
*input_line_pointer = c;
}
static void
tic54x_label (int ignored ATTRIBUTE_UNUSED)
{
- char *name = input_line_pointer;
+ char *name;
symbolS *symbolP;
int c;
ILLEGAL_WITHIN_STRUCT ();
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
symbolP = colon (name);
S_SET_STORAGE_CLASS (symbolP, C_STATLAB);
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
demand_empty_rest_of_line ();
}
static void
tic54x_mmregs (int ignored ATTRIBUTE_UNUSED)
{
- symbol *sym;
+ tic54x_symbol *sym;
ILLEGAL_WITHIN_STRUCT ();
- for (sym = (symbol *) mmregs; sym->name; sym++)
+ for (sym = (tic54x_symbol *) mmregs; sym->name; sym++)
{
symbolS *symbolP = symbol_new (sym->name, absolute_section,
- (valueT) sym->value, &zero_address_frag);
+ &zero_address_frag, sym->value);
SF_SET_LOCAL (symbolP);
symbol_table_insert (symbolP);
}
ILLEGAL_WITHIN_STRUCT ();
SKIP_WHITESPACE ();
- if (!is_end_of_line[(int) *input_line_pointer])
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
count = get_absolute_expression ();
- do_repeat (count, "LOOP", "ENDLOOP");
+ do_repeat ((size_t) count, "LOOP", "ENDLOOP");
}
/* Normally, endloop gets eaten by the preceding loop. */
ILLEGAL_WITHIN_STRUCT ();
SKIP_WHITESPACE ();
- if (!is_end_of_line[(int) *input_line_pointer])
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
cond = get_absolute_expression ();
if (cond)
if (mode == far_mode)
{
symbolS *symbolP = symbol_new ("__allow_far", absolute_section,
- (valueT) 1, &zero_address_frag);
+ &zero_address_frag, 1);
SF_SET_LOCAL (symbolP);
symbol_table_insert (symbolP);
}
}
static int address_mode_needs_set = 1;
+
static void
tic54x_address_mode (int mode)
{
if (*input_line_pointer == '"')
{
int len;
+
name = demand_copy_C_string (&len);
}
else
{
- char *section_name = input_line_pointer;
- c = get_symbol_end ();
- name = xmalloc (strlen (section_name) + 1);
- strcpy (name, section_name);
- *input_line_pointer = c;
+ char *section_name;
+
+ c = get_symbol_name (§ion_name);
+ name = xstrdup (section_name);
+ (void) restore_line_pointer (c);
}
seg = bfd_get_section_by_name (stdoutput, name);
ignore_rest_of_line ();
return;
}
- seg->flags |= SEC_BLOCK;
+ seg->flags |= SEC_TIC54X_BLOCK;
c = *input_line_pointer;
- if (!is_end_of_line[(int) c])
+ if (!is_end_of_line[(unsigned char) c])
++input_line_pointer;
}
if ((symbolP = symbol_find (name)) == NULL
&& (symbolP = md_undefined_symbol (name)) == NULL)
{
- symbolP = symbol_new (name, absolute_section, 0, &zero_address_frag);
+ symbolP = symbol_new (name, absolute_section, &zero_address_frag, 0);
S_SET_STORAGE_CLASS (symbolP, C_STAT);
}
free (name);
ignore_rest_of_line ();
return;
}
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
/* .var symbols start out with a null string. */
- name = strcpy (xmalloc (strlen (name) + 1), name);
- hash_insert (subsym_hash[macro_level], name, empty);
- *input_line_pointer = c;
+ name = xstrdup (name);
+ str_hash_insert (subsym_hash[macro_level], name, empty, 0);
+ c = restore_line_pointer (c);
if (c == ',')
{
++input_line_pointer;
- if (is_end_of_line[(int) *input_line_pointer])
+ if (is_end_of_line[(unsigned char) *input_line_pointer])
c = *input_line_pointer;
}
}
{
SKIP_WHITESPACE ();
len = 0;
- while (!is_end_of_line[(int) *input_line_pointer]
+ while (!is_end_of_line[(unsigned char) *input_line_pointer]
&& !ISSPACE (*input_line_pointer))
{
obstack_1grow (¬es, *input_line_pointer);
}
demand_empty_rest_of_line ();
- tic54x_set_default_include (0);
- path = xmalloc ((unsigned long) len + include_dir_maxlen + 5);
+ tic54x_set_default_include ();
+ path = XNEWVEC (char, (unsigned long) len + include_dir_maxlen + 5);
+
for (i = 0; i < include_dir_count; i++)
{
FILE *try;
+
strcpy (path, include_dirs[i]);
strcat (path, "/");
strcat (path, filename);
break;
}
}
+
if (i >= include_dir_count)
{
free (path);
abfd = bfd_openr (path, NULL);
if (!abfd)
{
- as_bad (_("Can't open macro library file '%s' for reading."), path);
- as_perror ("%s", path);
+ as_bad (_("can't open macro library file '%s' for reading: %s"),
+ path, bfd_errmsg (bfd_get_error ()));
ignore_rest_of_line ();
return;
}
{
/* Get a size at least as big as the archive member. */
bfd_size_type size = bfd_get_size (mbfd);
- char *buf = xmalloc (size);
+ char *buf = XNEWVEC (char, size);
char *fname = tmpnam (NULL);
FILE *ftmp;
/* We're not sure how big it is, but it will be smaller than "size". */
- bfd_bread (buf, size, mbfd);
+ size = bfd_bread (buf, size, mbfd);
/* Write to a temporary file, then use s_include to include it
a bit of a hack. */
ftmp = fopen (fname, "w+b");
fwrite ((void *) buf, size, 1, ftmp);
- if (buf[size - 1] != '\n')
+ if (size == 0 || buf[size - 1] != '\n')
fwrite ("\n", 1, 1, ftmp);
fclose (ftmp);
free (buf);
{ "emsg" , tic54x_message , 'e' },
{ "mmsg" , tic54x_message , 'm' },
{ "wmsg" , tic54x_message , 'w' },
-#if 0
- { "end" , s_end , 0 },
-#endif
{ "far_mode" , tic54x_address_mode , far_mode },
{ "fclist" , tic54x_fclist , 1 },
{ "fcnolist" , tic54x_fclist , 0 },
address. */
{ "length" , s_ignore , 0 },
{ "width" , s_ignore , 0 },
-#if 0
- { "list" , listing_list , 1 },
- { "nolist" , listing_list , 0 },
-#endif
{ "long" , tic54x_cons , 'l' },
{ "ulong" , tic54x_cons , 'L' },
{ "xlong" , tic54x_cons , 'x' },
{ "newblock" , tic54x_clear_local_labels, 0 },
{ "option" , s_ignore , 0 },
{ "p2align" , tic54x_p2align , 0 },
-#if 0
- { "page" , listing_eject , 0 },
-#endif
{ "sblock" , tic54x_sblock , 0 },
{ "sect" , tic54x_sect , '*' },
{ "set" , tic54x_set , 0 },
{ "endstruct", tic54x_endstruct , 0 },
{ "tab" , s_ignore , 0 },
{ "text" , tic54x_sect , 't' },
-#if 0
- { "title" , listing_title , 0 },
-#endif
{ "union" , tic54x_struct , 1 },
{ "endunion" , tic54x_endstruct , 1 },
{ "usect" , tic54x_usect , 0 },
{0 , 0 , 0 }
};
-#if 0
-/* For debugging, strings for each operand type. */
-static const char *optypes[] =
-{
- "none", "Xmem", "Ymem", "pmad", "dmad", "Smem", "Lmem", "MMR", "PA",
- "Sind", "xpmad", "xpmad+", "MMRX", "MMRY",
- "SRC1", "SRC", "RND", "DST",
- "ARX",
- "SHIFT", "SHFT",
- "B", "A", "lk", "TS", "k8", "16", "BITC", "CC", "CC2", "CC3", "123", "031",
- "k5", "k8u", "ASM", "T", "DP", "ARP", "k3", "lku", "N", "SBIT", "12",
- "k9", "TRN",
-};
-#endif
-
int
-md_parse_option (c, arg)
- int c;
- char *arg;
+md_parse_option (int c, const char *arg)
{
switch (c)
{
case OPTION_COFF_VERSION:
{
int version = atoi (arg);
+
if (version != 0 && version != 1 && version != 2)
as_fatal (_("Bad COFF version '%s'"), arg);
/* FIXME -- not yet implemented. */
break;
case OPTION_STDERR_TO_FILE:
{
- char *filename = arg;
+ const char *filename = arg;
FILE *fp = fopen (filename, "w+");
+
if (fp == NULL)
as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
fclose (fp);
deleting the local label hash between macro invocations. */
void
-tic54x_macro_start ()
+tic54x_macro_start (void)
{
- ++macro_level;
- subsym_hash[macro_level] = hash_new ();
- local_label_hash[macro_level] = hash_new ();
+ if (++macro_level >= MAX_SUBSYM_HASH)
+ {
+ as_fatal (_("Macro nesting is too deep"));
+ return;
+ }
+ subsym_hash[macro_level] = str_htab_create ();
+ local_label_hash[macro_level] = str_htab_create ();
}
void
-tic54x_macro_info (info)
- void *info;
+tic54x_macro_info (const macro_entry *macro)
{
- struct formal_struct
- {
- struct formal_struct *next; /* Next formal in list */
- sb name; /* Name of the formal */
- sb def; /* The default value */
- sb actual; /* The actual argument (changed on
- each expansion) */
- int index; /* The index of the formal
- 0 .. formal_count - 1 */
- } *entry;
- struct macro_struct
- {
- sb sub; /* Substitution text. */
- int formal_count; /* Number of formal args. */
- struct formal_struct *formals; /* Pointer to list of
- formal_structs. */
- struct hash_control *formal_hash; /* Hash table of formals. */
- } *macro;
-
- macro = (struct macro_struct *) info;
+ const formal_entry *entry;
/* Put the formal args into the substitution symbol table. */
for (entry = macro->formals; entry; entry = entry->next)
{
- char *name = strncpy (xmalloc (entry->name.len + 1),
- entry->name.ptr, entry->name.len);
- char *value = strncpy (xmalloc (entry->actual.len + 1),
- entry->actual.ptr, entry->actual.len);
+ char *name = xstrndup (entry->name.ptr, entry->name.len);
+ char *value = xstrndup (entry->actual.ptr, entry->actual.len);
+
name[entry->name.len] = '\0';
value[entry->actual.len] = '\0';
- hash_insert (subsym_hash[macro_level], name, value);
+ str_hash_insert (subsym_hash[macro_level], name, value, 0);
}
}
/* Get rid of this macro's .var's, arguments, and local labels. */
void
-tic54x_macro_end ()
+tic54x_macro_end (void)
{
- hash_die (subsym_hash[macro_level]);
+ htab_delete (subsym_hash[macro_level]);
subsym_hash[macro_level] = NULL;
- hash_die (local_label_hash[macro_level]);
+ htab_delete (local_label_hash[macro_level]);
local_label_hash[macro_level] = NULL;
--macro_level;
}
return strcmp (a, b);
}
-/* Return the index of the first occurence of B in A, or zero if none
+/* Return the index of the first occurrence of B in A, or zero if none
assumes b is an integer char value as a string. Index is one-based. */
static int
return 0;
}
- ptr = elem = xmalloc (strlen (listv) + 1);
- strcpy (elem, listv);
+ ptr = elem = xstrdup (listv);
while (*ptr && *ptr != ',')
++ptr;
*ptr++ = 0;
static int
subsym_iscons (char *a, char *ignore ATTRIBUTE_UNUSED)
{
- expressionS exp;
+ expressionS expn;
- parse_expression (a, &exp);
+ parse_expression (a, &expn);
- if (exp.X_op == O_constant)
+ if (expn.X_op == O_constant)
{
int len = strlen (a);
static int
subsym_isreg (char *a, char *ignore ATTRIBUTE_UNUSED)
{
- if (hash_find (reg_hash, a))
+ if (str_hash_find (reg_hash, a))
return 1;
- if (hash_find (mmreg_hash, a))
+ if (str_hash_find (mmreg_hash, a))
return 1;
return 0;
}
-/* Return the structrure size, given the stag. */
+/* Return the structure size, given the stag. */
static int
subsym_structsz (char *name, char *ignore ATTRIBUTE_UNUSED)
{
- struct stag *stag = (struct stag *) hash_find (stag_hash, name);
+ struct stag *stag = (struct stag *) str_hash_find (stag_hash, name);
+
if (stag)
return stag->size;
return zero, we punt and return zero. */
static int
-subsym_structacc (char *stag_name ATTRIBUTE_UNUSED,
- char *ignore ATTRIBUTE_UNUSED)
+subsym_structacc (char *stag_name ATTRIBUTE_UNUSED,
+ char *ignore ATTRIBUTE_UNUSED)
{
return 0;
}
static float
-math_ceil (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_ceil (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) ceil (arg1);
}
static float
-math_cvi (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_cvi (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (int) arg1;
}
static float
-math_floor (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_floor (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) floor (arg1);
}
}
static float
-math_int (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_int (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return ((float) ((int) arg1)) == arg1;
}
static float
-math_round (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_round (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return arg1 > 0 ? (int) (arg1 + 0.5) : (int) (arg1 - 0.5);
}
static float
-math_sgn (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_sgn (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (arg1 < 0) ? -1 : (arg1 ? 1 : 0);
}
static float
-math_trunc (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_trunc (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (int) arg1;
}
static float
-math_acos (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_acos (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) acos (arg1);
}
static float
-math_asin (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_asin (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) asin (arg1);
}
static float
-math_atan (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_atan (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) atan (arg1);
}
}
static float
-math_cosh (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_cosh (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) cosh (arg1);
}
static float
-math_cos (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_cos (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) cos (arg1);
}
static float
-math_cvf (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_cvf (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) arg1;
}
static float
-math_exp (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_exp (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) exp (arg1);
}
static float
-math_fabs (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_fabs (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) fabs (arg1);
}
}
static float
-math_log10 (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_log10 (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) log10 (arg1);
}
static float
-math_log (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_log (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) log (arg1);
}
}
static float
-math_sin (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_sin (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) sin (arg1);
}
static float
-math_sinh (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_sinh (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) sinh (arg1);
}
static float
-math_sqrt (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_sqrt (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) sqrt (arg1);
}
static float
-math_tan (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_tan (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) tan (arg1);
}
static float
-math_tanh (arg1, ignore)
- float arg1;
- float ignore ATTRIBUTE_UNUSED;
+math_tanh (float arg1, float ignore ATTRIBUTE_UNUSED)
{
return (float) tanh (arg1);
}
/* Built-in substitution symbol functions and math functions. */
typedef struct
{
- char *name;
+ const char *name;
int (*proc) (char *, char *);
int nargs;
} subsym_proc_entry;
typedef struct
{
- char *name;
+ const char *name;
float (*proc) (float, float);
int nargs;
int int_return;
};
void
-md_begin ()
+md_begin (void)
{
- template *tm;
- symbol *sym;
+ insn_template *tm;
+ tic54x_symbol *sym;
const subsym_proc_entry *subsym_proc;
const math_proc_entry *math_proc;
- const char *hash_err;
char **symname;
char *TIC54X_DIR = getenv ("TIC54X_DIR");
char *A_DIR = TIC54X_DIR ? TIC54X_DIR : getenv ("A_DIR");
local_label_id = 0;
- /* Look for A_DIR and add it to the include list. a */
+ /* Look for A_DIR and add it to the include list. */
if (A_DIR != NULL)
{
char *tmp = xstrdup (A_DIR);
+
do
{
char *next = strchr (tmp, ';');
+
if (next)
*next++ = '\0';
add_include_dir (tmp);
while (tmp != NULL);
}
- op_hash = hash_new ();
- for (tm = (template *) tic54x_optab; tm->name; tm++)
- {
- if (hash_find (op_hash, tm->name))
- continue;
- hash_err = hash_insert (op_hash, tm->name, (char *) tm);
- if (hash_err)
- as_fatal ("Internal Error: Can't hash %s: %s",
- tm->name, hash_err);
- }
- parop_hash = hash_new ();
- for (tm = (template *) tic54x_paroptab; tm->name; tm++)
- {
- if (hash_find (parop_hash, tm->name))
- continue;
- hash_err = hash_insert (parop_hash, tm->name, (char *) tm);
- if (hash_err)
- as_fatal ("Internal Error: Can't hash %s: %s",
- tm->name, hash_err);
- }
- reg_hash = hash_new ();
- for (sym = (symbol *) regs; sym->name; sym++)
+ op_hash = str_htab_create ();
+ for (tm = (insn_template *) tic54x_optab; tm->name; tm++)
+ str_hash_insert (op_hash, tm->name, tm, 0);
+
+ parop_hash = str_htab_create ();
+ for (tm = (insn_template *) tic54x_paroptab; tm->name; tm++)
+ str_hash_insert (parop_hash, tm->name, tm, 0);
+
+ reg_hash = str_htab_create ();
+ for (sym = (tic54x_symbol *) regs; sym->name; sym++)
{
/* Add basic registers to the symbol table. */
symbolS *symbolP = symbol_new (sym->name, absolute_section,
- (valueT) sym->value, &zero_address_frag);
+ &zero_address_frag, sym->value);
SF_SET_LOCAL (symbolP);
symbol_table_insert (symbolP);
- hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
- }
- for (sym = (symbol *) mmregs; sym->name; sym++)
- hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
- mmreg_hash = hash_new ();
- for (sym = (symbol *) mmregs; sym->name; sym++)
- {
- hash_err = hash_insert (mmreg_hash, sym->name, (char *) sym);
+ str_hash_insert (reg_hash, sym->name, sym, 0);
}
- cc_hash = hash_new ();
- for (sym = (symbol *) condition_codes; sym->name; sym++)
- {
- hash_err = hash_insert (cc_hash, sym->name, (char *) sym);
- }
- cc2_hash = hash_new ();
- for (sym = (symbol *) cc2_codes; sym->name; sym++)
- {
- hash_err = hash_insert (cc2_hash, sym->name, (char *) sym);
- }
- cc3_hash = hash_new ();
- for (sym = (symbol *) cc3_codes; sym->name; sym++)
- {
- hash_err = hash_insert (cc3_hash, sym->name, (char *) sym);
- }
- sbit_hash = hash_new ();
- for (sym = (symbol *) status_bits; sym->name; sym++)
- {
- hash_err = hash_insert (sbit_hash, sym->name, (char *) sym);
- }
- misc_symbol_hash = hash_new ();
+ for (sym = (tic54x_symbol *) mmregs; sym->name; sym++)
+ str_hash_insert (reg_hash, sym->name, sym, 0);
+ mmreg_hash = str_htab_create ();
+ for (sym = (tic54x_symbol *) mmregs; sym->name; sym++)
+ str_hash_insert (mmreg_hash, sym->name, sym, 0);
+
+ cc_hash = str_htab_create ();
+ for (sym = (tic54x_symbol *) condition_codes; sym->name; sym++)
+ str_hash_insert (cc_hash, sym->name, sym, 0);
+
+ cc2_hash = str_htab_create ();
+ for (sym = (tic54x_symbol *) cc2_codes; sym->name; sym++)
+ str_hash_insert (cc2_hash, sym->name, sym, 0);
+
+ cc3_hash = str_htab_create ();
+ for (sym = (tic54x_symbol *) cc3_codes; sym->name; sym++)
+ str_hash_insert (cc3_hash, sym->name, sym, 0);
+
+ sbit_hash = str_htab_create ();
+ for (sym = (tic54x_symbol *) status_bits; sym->name; sym++)
+ str_hash_insert (sbit_hash, sym->name, sym, 0);
+
+ misc_symbol_hash = str_htab_create ();
for (symname = (char **) misc_symbols; *symname; symname++)
- {
- hash_err = hash_insert (misc_symbol_hash, *symname, *symname);
- }
+ str_hash_insert (misc_symbol_hash, *symname, *symname, 0);
+
/* Only the base substitution table and local label table are initialized;
the others (for local macro substitution) get instantiated as needed. */
- local_label_hash[0] = hash_new ();
- subsym_hash[0] = hash_new ();
+ local_label_hash[0] = str_htab_create ();
+ subsym_hash[0] = str_htab_create ();
for (subsym_proc = subsym_procs; subsym_proc->name; subsym_proc++)
- {
- hash_err = hash_insert (subsym_hash[0], subsym_proc->name,
- (char *) subsym_proc);
- }
- math_hash = hash_new ();
+ str_hash_insert (subsym_hash[0], subsym_proc->name, subsym_proc, 0);
+
+ math_hash = str_htab_create ();
for (math_proc = math_procs; math_proc->name; math_proc++)
{
/* Insert into the main subsym hash for recognition; insert into
the math hash to actually store information. */
- hash_err = hash_insert (subsym_hash[0], math_proc->name,
- (char *) math_proc);
- hash_err = hash_insert (math_hash, math_proc->name,
- (char *) math_proc);
+ str_hash_insert (subsym_hash[0], math_proc->name, math_proc, 0);
+ str_hash_insert (math_hash, math_proc->name, math_proc, 0);
}
- subsym_recurse_hash = hash_new ();
- stag_hash = hash_new ();
+ subsym_recurse_hash = str_htab_create ();
+ stag_hash = str_htab_create ();
}
-typedef struct _tic54x_insn
-{
- const template *tm; /* Opcode template. */
-
- char mnemonic[MAX_LINE]; /* Opcode name/mnemonic. */
- char parmnemonic[MAX_LINE]; /* 2nd mnemonic of parallel insn. */
-
- int opcount;
- struct opstruct
- {
- char buf[MAX_LINE];
- enum optype type;
- expressionS exp;
- } operands[MAX_OPERANDS];
-
- int paropcount;
- struct opstruct paroperands[MAX_OPERANDS];
-
- int is_lkaddr;
- int lkoperand;
- int words; /* Size of insn in 16-bit words. */
- int using_default_dst; /* Do we need to explicitly set an
- omitted OP_DST operand? */
- struct
- {
- unsigned short word; /* Final encoded opcode data. */
- int unresolved;
- int r_nchars; /* Relocation size. */
- bfd_reloc_code_real_type r_type; /* Relocation type. */
- expressionS addr_expr; /* Storage for unresolved expressions. */
- } opcode[3];
-} tic54x_insn;
-
-static int encode_operand (tic54x_insn *, enum optype, struct opstruct *);
-static int encode_dmad (tic54x_insn *, struct opstruct *, int);
-static int operands_match (tic54x_insn *, struct opstruct *, int,
- const enum optype *, int, int);
-static int encode_address (tic54x_insn *, struct opstruct *);
-static int is_accumulator (struct opstruct *);
-
static int
is_accumulator (struct opstruct *operand)
{
int expecting_operand = 0;
int i;
- while (numexp < MAX_OPERANDS && !is_end_of_line[(int) *lptr])
+ while (numexp < MAX_OPERANDS && !is_end_of_line[(unsigned char) *lptr])
{
int paren_not_balanced = 0;
char *op_start, *op_end;
+
while (*lptr && ISSPACE (*lptr))
++lptr;
op_start = lptr;
{
if (paren_not_balanced)
{
- as_bad ("Unbalanced parenthesis in operand %d", numexp);
+ as_bad (_("Unbalanced parenthesis in operand %d"), numexp);
return -1;
}
else
if (op_end != op_start)
{
int len = op_end - op_start;
+
strncpy (operands[numexp].buf, op_start, len);
operands[numexp].buf[len] = 0;
/* Trim trailing spaces; while the preprocessor gets rid of most,
{
if (expecting_operand || *lptr == ',')
{
- as_bad ("Expecting operand after ','");
+ as_bad (_("Expecting operand after ','"));
return -1;
}
}
{
if (*++lptr == '\0')
{
- as_bad ("Expecting operand after ','");
+ as_bad (_("Expecting operand after ','"));
return -1;
}
expecting_operand = 1;
while (*lptr && ISSPACE (*lptr++))
;
- if (!is_end_of_line[(int) *lptr])
+ if (!is_end_of_line[(unsigned char) *lptr])
{
- as_bad ("Extra junk on line");
+ as_bad (_("Extra junk on line"));
return -1;
}
{
/* Indirect. */
char *paren = strchr (operands[i].buf, '(');
+
/* Allow immediate syntax in the inner expression. */
if (paren && paren[1] == '#')
*++paren = '(';
int len = strlen (paren);
char *end = paren + len;
int c;
+
while (end[-1] != ')')
if (--end <= paren)
{
{
return (is_absolute (operand)
|| is_immediate (operand)
- || hash_find (mmreg_hash, operand->buf) != 0);
+ || str_hash_find (mmreg_hash, operand->buf) != 0);
}
static int
return strncasecmp ("ar", operand->buf, 2) == 0
&& ISDIGIT (operand->buf[2]);
case OP_SBIT:
- return hash_find (sbit_hash, operand->buf) != 0 || is_absolute (operand);
+ return str_hash_find (sbit_hash, operand->buf) != 0 || is_absolute (operand);
case OP_CC:
- return hash_find (cc_hash, operand->buf) != 0;
+ return str_hash_find (cc_hash, operand->buf) != 0;
case OP_CC2:
- return hash_find (cc2_hash, operand->buf) != 0;
+ return str_hash_find (cc2_hash, operand->buf) != 0;
case OP_CC3:
- return hash_find (cc3_hash, operand->buf) != 0
+ return str_hash_find (cc3_hash, operand->buf) != 0
|| is_immediate (operand) || is_absolute (operand);
case OP_16:
return (is_immediate (operand) || is_absolute (operand))
}
static int
-operands_match (insn, operands, opcount, refoptype, minops, maxops)
- tic54x_insn *insn;
- struct opstruct *operands;
- int opcount;
- const enum optype *refoptype;
- int minops, maxops;
+operands_match (tic54x_insn *insn,
+ struct opstruct *operands,
+ int opcount,
+ const enum optype *refoptype,
+ int minops,
+ int maxops)
{
int op = 0, refop = 0;
if (opcount == 0 && minops == 0)
- {
- return 1;
- }
+ return 1;
while (op <= maxops && refop <= maxops)
{
2 for the upper 7 bits of a 23-bit address (LDX). */
static int
-encode_dmad (insn, operand, xpc_code)
- tic54x_insn *insn;
- struct opstruct *operand;
- int xpc_code;
+encode_dmad (tic54x_insn *insn, struct opstruct *operand, int xpc_code)
{
int op = 1 + insn->is_lkaddr;
if (insn->opcode[op].addr_expr.X_op == O_constant)
{
valueT value = insn->opcode[op].addr_expr.X_add_number;
+
if (xpc_code == 1)
{
insn->opcode[0].word &= 0xFF80;
/* 7-bit direct address encoding. */
static int
-encode_address (insn, operand)
- tic54x_insn *insn;
- struct opstruct *operand;
+encode_address (tic54x_insn *insn, struct opstruct *operand)
{
/* Assumes that dma addresses are *always* in word 0 of the opcode. */
insn->opcode[0].addr_expr = operand->exp;
insn->opcode[0].word |= (operand->exp.X_add_number & 0x7F);
else
{
+ if (operand->exp.X_op == O_register)
+ as_bad (_("Use the .mmregs directive to use memory-mapped register names such as '%s'"), operand->buf);
/* Do the fixup later; just store the expression. */
insn->opcode[0].r_nchars = 1;
insn->opcode[0].r_type = BFD_RELOC_TIC54X_PARTLS7;
}
static int
-encode_integer (tic54x_insn *insn,
- struct opstruct *operand,
- int which, int min, int max, unsigned short mask)
+encode_integer (tic54x_insn *insn,
+ struct opstruct *operand,
+ int which,
+ int min,
+ int max,
+ unsigned short mask)
{
long parse, integer;
static int
encode_condition (tic54x_insn *insn, struct opstruct *operand)
{
- symbol *cc = (symbol *) hash_find (cc_hash, operand->buf);
+ tic54x_symbol *cc = (tic54x_symbol *) str_hash_find (cc_hash, operand->buf);
if (!cc)
{
as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
return 0;
}
}
- else if (((insn->opcode[0].word & CATG_A2) && (cc->value & CATG_A2)) ||
- ((insn->opcode[0].word & CATG_B2) && (cc->value & CATG_B2)) ||
- ((insn->opcode[0].word & CATG_C2) && (cc->value & CATG_C2)))
+ else if ( ((insn->opcode[0].word & CATG_A2) && (cc->value & CATG_A2))
+ || ((insn->opcode[0].word & CATG_B2) && (cc->value & CATG_B2))
+ || ((insn->opcode[0].word & CATG_C2) && (cc->value & CATG_C2)))
{
as_bad (_("Duplicate %s conditional"), operand->buf);
return 0;
static int
encode_cc3 (tic54x_insn *insn, struct opstruct *operand)
{
- symbol *cc3 = (symbol *) hash_find (cc3_hash, operand->buf);
+ tic54x_symbol *cc3 = (tic54x_symbol *) str_hash_find (cc3_hash, operand->buf);
int value = cc3 ? cc3->value : operand->exp.X_add_number << 8;
if ((value & 0x0300) != value)
encode_arx (tic54x_insn *insn, struct opstruct *operand)
{
int arf = strlen (operand->buf) >= 3 ? operand->buf[2] - '0' : -1;
+
if (strncasecmp ("ar", operand->buf, 2) || arf < 0 || arf > 7)
{
as_bad (_("Invalid auxiliary register (use AR0-AR7)"));
static int
encode_cc2 (tic54x_insn *insn, struct opstruct *operand)
{
- symbol *cc2 = (symbol *) hash_find (cc2_hash, operand->buf);
+ tic54x_symbol *cc2 = (tic54x_symbol *) str_hash_find (cc2_hash, operand->buf);
+
if (!cc2)
{
as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
}
static int
-encode_operand (insn, type, operand)
- tic54x_insn *insn;
- enum optype type;
- struct opstruct *operand;
+encode_operand (tic54x_insn *insn, enum optype type, struct opstruct *operand)
{
int ext = (insn->tm->flags & FL_EXT) != 0;
}
return 1;
case OP_RND:
- /* Make sure this agrees with with the OP_DST operand. */
+ /* Make sure this agrees with the OP_DST operand. */
if (!((TOUPPER (operand->buf[0]) == 'B') ^
((insn->opcode[0].word & (1 << 8)) != 0)))
{
0, 65535, 0xFFFF);
case OP_SBIT:
{
- symbol *sbit = (symbol *) hash_find (sbit_hash, operand->buf);
+ tic54x_symbol *sbit = (tic54x_symbol *)
+ str_hash_find (sbit_hash, operand->buf);
int value = is_absolute (operand) ?
operand->exp.X_add_number : (sbit ? sbit->value : -1);
int reg = 0;
}
/* Guess the register based on the status bit; "ovb" is the last
status bit defined for st0. */
- if (sbit > (symbol *) hash_find (sbit_hash, "ovb"))
+ if (sbit > (tic54x_symbol *) str_hash_find (sbit_hash, "ovb"))
reg = 1;
}
if (value == -1)
emit_insn (tic54x_insn *insn)
{
int i;
- flagword oldflags = bfd_get_section_flags (stdoutput, now_seg);
+ flagword oldflags = bfd_section_flags (now_seg);
flagword flags = oldflags | SEC_CODE;
- if (! bfd_set_section_flags (stdoutput, now_seg, flags))
+ if (!bfd_set_section_flags (now_seg, flags))
as_warn (_("error setting flags for \"%s\": %s"),
- bfd_section_name (stdoutput, now_seg),
+ bfd_section_name (now_seg),
bfd_errmsg (bfd_get_error ()));
for (i = 0; i < insn->words; i++)
if (insn->opcode[i].unresolved)
fix_new_exp (frag_now, p - frag_now->fr_literal,
insn->opcode[i].r_nchars, &insn->opcode[i].addr_expr,
- false, insn->opcode[i].r_type);
+ FALSE, insn->opcode[i].r_type);
}
}
for (i = 0; i < insn->opcount; i++)
{
enum optype type = insn->operands[i].type;
+
if (!encode_operand (insn, type, &insn->operands[i]))
return 0;
}
for (i = 0; i < insn->paropcount; i++)
{
enum optype partype = insn->paroperands[i].type;
+
if (!encode_operand (insn, partype, &insn->paroperands[i]))
return 0;
}
return 1;
}
- if (((OPTYPE (insn->tm->operand_types[0]) == OP_Smem
+ if ( ((OPTYPE (insn->tm->operand_types[0]) == OP_Smem
&& OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT)
|| (OPTYPE (insn->tm->operand_types[0]) == OP_Xmem
- && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT))
+ && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT))
&& is_zero (insn->operands[1])
&& insn->opcount == 3)
{
static int
tic54x_parse_insn (tic54x_insn *insn, char *line)
{
- insn->tm = (template *) hash_find (op_hash, insn->mnemonic);
+ insn->tm = (insn_template *) str_hash_find (op_hash, insn->mnemonic);
if (!insn->tm)
{
as_bad (_("Unrecognized instruction \"%s\""), insn->mnemonic);
/* SUCCESS! now try some optimizations. */
if (optimize_insn (insn))
{
- insn->tm = (template *) hash_find (op_hash,
- insn->mnemonic);
+ insn->tm = (insn_template *) str_hash_find (op_hash,
+ insn->mnemonic);
continue;
}
next_line_shows_parallel (char *next_line)
{
/* Look for the second half. */
- while (ISSPACE (*next_line))
+ while (*next_line != 0 && ISSPACE (*next_line))
++next_line;
return (next_line[0] == PARALLEL_SEPARATOR
static int
tic54x_parse_parallel_insn_firstline (tic54x_insn *insn, char *line)
{
- insn->tm = (template *) hash_find (parop_hash, insn->mnemonic);
+ insn->tm = (insn_template *) str_hash_find (parop_hash, insn->mnemonic);
if (!insn->tm)
{
as_bad (_("Unrecognized parallel instruction \"%s\""),
if (strcasecmp (insn->tm->parname, insn->parmnemonic) == 0)
{
valid_mnemonic = 1;
+
if (insn->paropcount >= insn->tm->minops
&& insn->paropcount <= insn->tm->maxops
&& operands_match (insn, insn->paroperands,
insn->paropcount,
insn->tm->paroperand_types,
insn->tm->minops, insn->tm->maxops))
- {
- return 1;
- }
+ return 1;
}
++(insn->tm);
}
replacement on the value. */
static char *
-subsym_get_arg (char *line, char *terminators, char **str, int nosub)
+subsym_get_arg (char *line, const char *terminators, char **str, int nosub)
{
char *ptr = line;
char *endp;
while (ISDIGIT (*ptr))
++ptr;
endp = ptr;
- *str = xmalloc (ptr - line + 1);
- strncpy (*str, line, ptr - line);
- (*str)[ptr - line] = 0;
+ *str = xmemdup0 (line, ptr - line);
}
else if (is_string)
{
char *savedp = input_line_pointer;
int len;
+
input_line_pointer = ptr;
*str = demand_copy_C_string (&len);
endp = input_line_pointer;
}
else
{
- char *term = terminators;
+ const char *term = terminators;
char *value = NULL;
while (*ptr && *ptr != *term)
++term;
}
endp = ptr;
- *str = xmalloc (ptr - line + 1);
- strncpy (*str, line, ptr - line);
- (*str)[ptr - line] = 0;
+ *str = xmemdup0 (line, ptr - line);
/* Do simple substitution, if available. */
if (!nosub && (value = subsym_lookup (*str, macro_level)) != NULL)
*str = value;
that's compatible w/TI's assembler. */
static void
-subsym_create_or_replace (name, value)
- char *name;
- char *value;
+subsym_create_or_replace (char *name, char *value)
{
int i;
for (i = macro_level; i > 0; i--)
- {
- if (hash_find (subsym_hash[i], name))
- {
- hash_replace (subsym_hash[i], name, value);
- return;
- }
- }
- if (hash_find (subsym_hash[0], name))
- hash_replace (subsym_hash[0], name, value);
- else
- hash_insert (subsym_hash[0], name, value);
+ if (str_hash_find (subsym_hash[i], name))
+ {
+ str_hash_insert (subsym_hash[i], name, value, 1);
+ return;
+ }
+ str_hash_insert (subsym_hash[0], name, value, 1);
}
/* Look up the substitution string replacement for the given symbol.
- Start with the innermost macro substituion table given and work
+ Start with the innermost macro substitution table given and work
outwards. */
static char *
-subsym_lookup (name, nest_level)
- char *name;
- int nest_level;
+subsym_lookup (char *name, int nest_level)
{
- char *value = hash_find (subsym_hash[nest_level], name);
+ char *value = str_hash_find (subsym_hash[nest_level], name);
if (value || nest_level == 0)
return value;
char *tmp;
/* Work with a copy of the input line. */
- replacement = xmalloc (strlen (line) + 1);
- strcpy (replacement, line);
+ replacement = xstrdup (line);
ptr = head = replacement;
if (strstr (line, ".if")
|| strstr (line, ".elseif")
|| strstr (line, ".break"))
- {
- line_conditional = 1;
- }
+ line_conditional = 1;
/* Watch out for .eval, so that we avoid doing substitution on the
symbol being assigned a value. */
if (strstr (line, ".macro"))
return line;
- while (!is_end_of_line[(int) *ptr])
+ unsigned char current_char;
+ while (!is_end_of_line[(current_char = * (unsigned char *) ptr)])
{
- int current_char = *ptr;
-
/* Need to update this since LINE may have been modified. */
if (eval_line)
eval_end = strrchr (ptr, ',');
continue;
}
*ptr++ = '\0';
- tmp = xmalloc (strlen (head) + 2 + strlen (ptr) + 1);
- sprintf (tmp, "%s==%s", head, ptr);
+ tmp = concat (head, "==", ptr, (char *) NULL);
/* Continue examining after the '=='. */
ptr = tmp + strlen (head) + 2;
free (replacement);
if (forced)
++ptr;
- name = input_line_pointer = ptr;
- c = get_symbol_end ();
+ input_line_pointer = ptr;
+ c = get_symbol_name (&name);
/* '?' is not normally part of a symbol, but it IS part of a local
label. */
if (c == '?')
}
/* Avoid infinite recursion; if a symbol shows up a second time for
substitution, leave it as is. */
- if (hash_find (subsym_recurse_hash, name) == NULL)
+ if (str_hash_find (subsym_recurse_hash, name) == NULL)
value = subsym_lookup (name, macro_level);
else
as_warn (_("%s symbol recursion stopped at "
{
/* Use an existing identifier for that label if, available, or
create a new, unique identifier. */
- value = hash_find (local_label_hash[macro_level], name);
+ value = str_hash_find (local_label_hash[macro_level], name);
if (value == NULL)
{
char digit[11];
- char *namecopy = strcpy (xmalloc (strlen (name) + 1), name);
+ char *namecopy = xstrdup (name);
+
value = strcpy (xmalloc (strlen (name) + sizeof (digit) + 1),
name);
if (*value != '$')
value[strlen (value) - 1] = '\0';
sprintf (digit, ".%d", local_label_id++);
strcat (value, digit);
- hash_insert (local_label_hash[macro_level], namecopy, value);
+ str_hash_insert (local_label_hash[macro_level],
+ namecopy, value, 0);
}
/* Indicate where to continue looking for substitutions. */
ptr = tail;
else if (value != NULL && *name == '$')
{
subsym_proc_entry *entry = (subsym_proc_entry *) value;
- math_proc_entry *math_entry = hash_find (math_hash, name);
+ math_proc_entry *math_entry = str_hash_find (math_hash, name);
char *arg1, *arg2 = NULL;
*ptr = c;
++ptr;
if (math_entry != NULL)
{
- float arg1, arg2 = 0;
+ float farg1, farg2 = 0;
volatile float fresult;
- arg1 = (float) strtod (ptr, &ptr);
+ farg1 = (float) strtod (ptr, &ptr);
if (math_entry->nargs == 2)
{
if (*ptr++ != ',')
as_bad (_("Expecting second argument"));
break;
}
- arg2 = (float) strtod (ptr, &ptr);
+ farg2 = (float) strtod (ptr, &ptr);
}
- fresult = (*math_entry->proc) (arg1, arg2);
- value = xmalloc (128);
+ fresult = (*math_entry->proc) (farg1, farg2);
+ value = XNEWVEC (char, 128);
if (math_entry->int_return)
sprintf (value, "%d", (int) fresult);
else
int val;
int arg_type[2] = { *ptr == '"' , 0 };
int ismember = !strcmp (entry->name, "$ismember");
+
/* Parse one or two args, which must be a substitution
symbol, string or a character-string constant. */
/* For all functions, a string or substitution symbol may be
break;
}
val = (*entry->proc) (arg1, arg2);
- value = xmalloc (64);
+ value = XNEWVEC (char, 64);
sprintf (value, "%d", val);
}
/* Fix things up to replace the entire expression, not just the
substitutions are performed, or a substitution that has been
previously made is encountered again.
- put the symbol into the recursion hash table so we only
+ Put the symbol into the recursion hash table so we only
try to replace a symbol once. */
if (recurse)
{
- hash_insert (subsym_recurse_hash, name, name);
+ str_hash_insert (subsym_recurse_hash, name, name, 0);
value = subsym_substitute (value, macro_level > 0);
- hash_delete (subsym_recurse_hash, name);
+ str_hash_delete (subsym_recurse_hash, name);
}
/* Temporarily zero-terminate where the symbol started. */
{
/* Subscripted substitution symbol -- use just the
indicated portion of the string; the description
- kinda indicates that forced substituion is not
+ kinda indicates that forced substitution is not
supposed to be recursive, but I'm not sure. */
unsigned beg, len = 1; /* default to a single char */
- char *newval = strcpy (xmalloc (strlen (value) + 1),
- value);
+ char *newval = xstrdup (value);
savedp = input_line_pointer;
input_line_pointer = tail + 1;
if (beg < 1)
{
as_bad (_("Invalid subscript (use 1 to %d)"),
- strlen (value));
+ (int) strlen (value));
break;
}
if (*input_line_pointer == ',')
len = get_absolute_expression ();
if (beg + len > strlen (value))
{
- as_bad (_("Invalid length (use 0 to %d"),
- strlen (value) - beg);
+ as_bad (_("Invalid length (use 0 to %d)"),
+ (int) strlen (value) - beg);
break;
}
}
break;
}
++tail;
-#if 0
- /* Try to replace required whitespace
- eliminated by the preprocessor; technically, a forced
- substitution could come anywhere, even mid-symbol,
- e.g. if x is "0", 'sym:x:end' should result in 'sym0end',
- but 'sym:x: end' should result in 'sym0 end'.
- FIXME -- this should really be fixed in the preprocessor,
- but would require several new states;
- KEEP_WHITE_AROUND_COLON does part of the job, but isn't
- complete. */
- if ((is_part_of_name (tail[1])
- && tail[1] != '.'
- && tail[1] != '$')
- || tail[1] == '\0' || tail[1] == ',' || tail[1] == '"')
- ++tail;
- else
- *tail = ' ';
-#endif
}
else
/* Restore the character after the symbol end. */
returns the new buffer limit. */
void
-tic54x_start_line_hook ()
+tic54x_start_line_hook (void)
{
char *line, *endp;
char *replacement = NULL;
/* Work with a copy of the input line, including EOL char. */
- endp = input_line_pointer;
- while (!is_end_of_line[(int) *endp++])
- ;
- line = xmalloc (endp - input_line_pointer + 1);
- strncpy (line, input_line_pointer, endp - input_line_pointer + 1);
- line[endp - input_line_pointer] = 0;
+ for (endp = input_line_pointer; *endp != 0; )
+ if (is_end_of_line[(unsigned char) *endp++])
+ break;
+
+ line = xmemdup0 (input_line_pointer, endp - input_line_pointer);
/* Scan ahead for parallel insns. */
- parallel_on_next_line_hint = next_line_shows_parallel (endp + 1);
+ parallel_on_next_line_hint = next_line_shows_parallel (endp);
/* If within a macro, first process forced replacements. */
if (macro_level > 0)
machine dependent instruction. This function is supposed to emit
the frags/bytes it assembles to. */
void
-md_assemble (line)
- char *line;
+md_assemble (char *line)
{
static int repeat_slot = 0;
static int delay_slots = 0; /* How many delay slots left to fill? */
int c;
input_line_pointer = line;
- c = get_symbol_end ();
+ c = get_symbol_name (&line);
if (cpu == VNONE)
cpu = V542;
{
if (words > delay_slots)
{
- as_bad (_("Instruction does not fit in available delay "
- "slots (%d-word insn, %d slots left)"),
+ as_bad (ngettext ("Instruction does not fit in available "
+ "delay slots (%d-word insn, %d slot left)",
+ "Instruction does not fit in available "
+ "delay slots (%d-word insn, %d slots left)",
+ delay_slots),
words, delay_slots);
delay_slots = 0;
return;
{
if (words > delay_slots)
{
- as_warn (_("Instruction does not fit in available delay "
- "slots (%d-word insn, %d slots left). "
- "Resulting behavior is undefined."),
+ as_warn (ngettext ("Instruction does not fit in available "
+ "delay slots (%d-word insn, %d slot left). "
+ "Resulting behavior is undefined.",
+ "Instruction does not fit in available "
+ "delay slots (%d-word insn, %d slots left). "
+ "Resulting behavior is undefined.",
+ delay_slots),
words, delay_slots);
delay_slots = 0;
return;
a ".file" symbol. */
void
-tic54x_adjust_symtab ()
+tic54x_adjust_symtab (void)
{
if (symbol_rootP == NULL
|| S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
{
- char *filename;
unsigned lineno;
- as_where (&filename, &lineno);
- c_dot_file_symbol (filename);
+ const char * filename = as_where (&lineno);
+ c_dot_file_symbol (filename, 0);
}
}
FIXME -- obviously this isn't done yet. These locals still show up in the
symbol table. */
void
-tic54x_define_label (sym)
- symbolS *sym;
+tic54x_define_label (symbolS *sym)
{
-#if 0
- static int local_label_count = 0;
- const char *name = S_GET_NAME (sym);
-#endif
-
/* Just in case we need this later; note that this is not necessarily the
same thing as line_label...
When aligning or assigning labels to fields, sometimes the label is
/* Try to parse something that normal parsing failed at. */
symbolS *
-tic54x_undefined_symbol (name)
- char *name;
+tic54x_undefined_symbol (char *name)
{
- symbol *sym;
+ tic54x_symbol *sym;
/* Not sure how to handle predefined symbols. */
- if ((sym = (symbol *) hash_find (cc_hash, name)) != NULL ||
- (sym = (symbol *) hash_find (cc2_hash, name)) != NULL ||
- (sym = (symbol *) hash_find (cc3_hash, name)) != NULL ||
- (sym = (symbol *) hash_find (misc_symbol_hash, name)) != NULL ||
- (sym = (symbol *) hash_find (sbit_hash, name)) != NULL)
+ if ((sym = (tic54x_symbol *) str_hash_find (cc_hash, name)) != NULL
+ || (sym = (tic54x_symbol *) str_hash_find (cc2_hash, name)) != NULL
+ || (sym = (tic54x_symbol *) str_hash_find (cc3_hash, name)) != NULL
+ || str_hash_find (misc_symbol_hash, name) != NULL
+ || (sym = (tic54x_symbol *) str_hash_find (sbit_hash, name)) != NULL
+ || (sym = (tic54x_symbol *) str_hash_find (reg_hash, name)) != NULL
+ || (sym = (tic54x_symbol *) str_hash_find (mmreg_hash, name)) != NULL
+ || !strcasecmp (name, "a")
+ || !strcasecmp (name, "b"))
{
- return symbol_new (name, reg_section,
- (valueT) sym->value,
- &zero_address_frag);
- }
-
- if ((sym = (symbol *) hash_find (reg_hash, name)) != NULL ||
- (sym = (symbol *) hash_find (mmreg_hash, name)) != NULL ||
- !strcasecmp (name, "a") || !strcasecmp (name, "b"))
- {
- return symbol_new (name, reg_section,
- (valueT) sym ? sym->value : 0,
- &zero_address_frag);
+ return symbol_new (name, reg_section, &zero_address_frag,
+ sym ? sym->value : 0);
}
return NULL;
it. */
int
-tic54x_parse_name (name, exp)
- char *name ATTRIBUTE_UNUSED;
- expressionS *exp ATTRIBUTE_UNUSED;
+tic54x_parse_name (char *name ATTRIBUTE_UNUSED,
+ expressionS *expn ATTRIBUTE_UNUSED)
{
-#if 0
- symbol *sym = (symbol *) hash_find (mmreg_hash, name);
-
- /* If it's a MMREG, replace it with its constant value. */
- if (sym)
- {
- exp->X_op = O_constant;
- exp->X_add_number = sym->value;
- return 1;
- }
-#endif
return 0;
}
-char *
-md_atof (type, literalP, sizeP)
- int type;
- char *literalP;
- int *sizeP;
+const char *
+md_atof (int type, char *literalP, int *sizeP)
{
-#define MAX_LITTLENUMS 2
- LITTLENUM_TYPE words[MAX_LITTLENUMS];
- LITTLENUM_TYPE *word;
- /* Only one precision on the c54x. */
- int prec = 2;
- char *t = atof_ieee (input_line_pointer, type, words);
- if (t)
- input_line_pointer = t;
- *sizeP = 4;
-
/* Target data is little-endian, but floats are stored
big-"word"ian. ugh. */
- for (word = words; prec--;)
- {
- md_number_to_chars (literalP, (long) (*word++), sizeof (LITTLENUM_TYPE));
- literalP += sizeof (LITTLENUM_TYPE);
- }
-
- return 0;
+ return ieee_md_atof (type, literalP, sizeP, TRUE);
}
arelent *
-tc_gen_reloc (section, fixP)
- asection *section;
- fixS *fixP;
+tc_gen_reloc (asection *section, fixS *fixP)
{
arelent *rel;
bfd_reloc_code_real_type code = fixP->fx_r_type;
asymbol *sym = symbol_get_bfdsym (fixP->fx_addsy);
- rel = (arelent *) xmalloc (sizeof (arelent));
- rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ rel = XNEW (arelent);
+ rel->sym_ptr_ptr = XNEW (asymbol *);
*rel->sym_ptr_ptr = sym;
/* We assume that all rel->address are host byte offsets. */
rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
/* Handle cons expressions. */
void
-tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *exp)
+tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn,
+ bfd_reloc_code_real_type r)
{
- bfd_reloc_code_real_type r;
switch (octets)
{
default:
r = BFD_RELOC_32;
break;
}
- fix_new_exp (frag, where, octets, exp, 0, r);
+ fix_new_exp (frag, where, octets, expn, 0, r);
}
/* Attempt to simplify or even eliminate a fixup.
If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry. */
void
-md_apply_fix3 (fixP, valP, seg)
- fixS *fixP;
- valueT * valP;
- segT seg ATTRIBUTE_UNUSED;
+md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
{
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
valueT val = * valP;
don't need to do anything here, since BFD does the proper encoding. */
valueT
-md_section_align (segment, section_size)
- segT segment ATTRIBUTE_UNUSED;
- valueT section_size;
+md_section_align (segT segment ATTRIBUTE_UNUSED, valueT section_size)
{
return section_size;
}
long
-md_pcrel_from (fixP)
- fixS *fixP ATTRIBUTE_UNUSED;
+md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
{
return 0;
}
-#if defined OBJ_COFF
-
-short
-tc_coff_fix2rtype (fixP)
- fixS *fixP;
-{
- return (fixP->fx_r_type);
-}
-
-#endif /* OBJ_COFF */
-
/* Mostly little-endian, but longwords (4 octets) get MS word stored
first. */
void
-tic54x_number_to_chars (buf, val, n)
- char *buf;
- valueT val;
- int n;
+tic54x_number_to_chars (char *buf, valueT val, int n)
{
if (n != 4)
number_to_chars_littleendian (buf, val, n);
}
int
-tic54x_estimate_size_before_relax (frag, seg)
- fragS *frag ATTRIBUTE_UNUSED;
- segT seg ATTRIBUTE_UNUSED;
+tic54x_estimate_size_before_relax (fragS *frag ATTRIBUTE_UNUSED,
+ segT seg ATTRIBUTE_UNUSED)
{
return 0;
}
to symbols being in different frags. return number of octets added. */
int
-tic54x_relax_frag (frag, stretch)
- fragS *frag;
- long stretch ATTRIBUTE_UNUSED;
+tic54x_relax_frag (fragS *frag, long stretch ATTRIBUTE_UNUSED)
{
symbolS *sym = frag->fr_symbol;
int growth = 0;
if (bit_offset != 0 && available >= size)
{
char *p = prev_frag->fr_literal;
+
valueT value = bi->value;
value <<= available - size;
value |= ((unsigned short) p[1] << 8) | p[0];
else
{
char *p = frag->fr_literal;
+
valueT value = bi->value << (16 - size);
md_number_to_chars (p, value, 2);
if ((frag->tc_frag_data = size) == 16)
}
void
-tic54x_convert_frag (abfd, seg, frag)
- bfd *abfd ATTRIBUTE_UNUSED;
- segT seg ATTRIBUTE_UNUSED;
- fragS *frag;
+tic54x_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
+ segT seg ATTRIBUTE_UNUSED,
+ fragS *frag)
{
/* Offset is in bytes. */
frag->fr_offset = (frag->fr_next->fr_address
syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
I guess, except I've never seen a definition of MRI syntax).
- C is the character that used to be at *REST, which points to the end of the
- label.
-
Don't allow labels to start with '.' */
int
-tic54x_start_label (c, rest)
- int c;
- char *rest;
+tic54x_start_label (char * label_start, int nul_char, int next_char)
{
+ char *rest;
+
/* If within .struct/.union, no auto line labels, please. */
if (current_stag != NULL)
return 0;
/* Disallow labels starting with "." */
- if (c != ':')
+ if (next_char != ':')
{
- char *label = rest;
- while (!is_end_of_line[(int) label[-1]])
- --label;
- if (*label == '.')
+ if (*label_start == '.')
{
- as_bad (_("Invalid label '%s'"), label);
+ as_bad (_("Invalid label '%s'"), label_start);
return 0;
}
}
- if (is_end_of_line[(int) c])
+ if (is_end_of_line[(unsigned char) next_char])
return 1;
- if (ISSPACE (c))
- while (ISSPACE (c = *++rest))
- ;
- if (c == '.')
- {
- /* Don't let colon () define a label for any of these... */
- return (strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4]))
- && (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7]))
- && (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6]))
- && (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6]))
- && (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4]))
- && (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4]));
- }
+ rest = input_line_pointer;
+ if (nul_char == '"')
+ ++rest;
+ while (ISSPACE (next_char))
+ next_char = *++rest;
+ if (next_char != '.')
+ return 1;
- return 1;
+ /* Don't let colon () define a label for any of these... */
+ return ((strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4]))
+ && (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7]))
+ && (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6]))
+ && (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6]))
+ && (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4]))
+ && (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4])));
}