/* tc-i860.c -- Assembler for the Intel i860 architecture.
- Copyright (C) 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000
+ Copyright 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
Brought back from the dead and completely reworked
with GAS; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "as.h"
+#include "safe-ctype.h"
#include "subsegs.h"
#include "opcode/i860.h"
#include "elf/i860.h"
-
/* Defined by default since this is primarily a SVR4/860 assembler.
However, I'm trying to leave the door open for Intel syntax. Of course,
if full support for anything other than SVR4 is done, then we should
select this based on a command-line flag. */
#define SYNTAX_SVR4
-
/* The opcode hash table. */
static struct hash_control *op_hash = NULL;
As in 0f12.456 or 0d1.2345e12. */
const char FLT_CHARS[] = "rRsSfFdDxXpP";
-
/* Register prefix. */
#ifdef SYNTAX_SVR4
static const char reg_prefix = '%';
static const char reg_prefix = 0;
#endif
-
struct i860_it
{
char *error;
/* If true, then warn if any pseudo operations were expanded. */
static int target_warn_expand = 0;
-
/* Prototypes. */
static void i860_process_insn PARAMS ((char *));
static void s_dual PARAMS ((int));
static void print_insn PARAMS ((struct i860_it *));
#endif
-
const pseudo_typeS md_pseudo_table[] =
{
#ifdef OBJ_ELF
{NULL, 0, 0},
};
-
/* Dual-instruction mode handling. */
enum dual
{
};
static enum dual dual_mode = DUAL_OFF;
-
/* Handle ".dual" directive. */
static void
s_dual (ignore)
dual_mode = DUAL_ON;
}
-
/* Handle ".enddual" directive. */
static void
s_enddual (ignore)
dual_mode = DUAL_OFF;
}
-
/* Temporary register used when expanding assembler pseudo operations. */
static int atmp = 31;
demand_empty_rest_of_line ();
}
-
/* This function is called once, at assembler startup time. It should
set up all the tables and data structures that the MD part of the
assembler will need. */
as_fatal (_("Defective assembler. No assembly attempted."));
}
-
/* This is the core of the machine-dependent assembler. STR points to a
machine dependent instruction. This function emits the frags/bytes
it assembles to. */
the_insn.reloc);
/* Despite the odd name, this is a scratch field. We use
- it to encode operand type information. */
+ it to encode operand type information. */
fix->fx_addnumber = the_insn.fup;
}
the_insn = pseudo[++i];
}
-
/* Assemble the instruction pointed to by STR. */
static void
i860_process_insn (str)
opcode = 0;
#endif
- for (s = str; islower (*s) || *s == '.' || *s == '3'
+ for (s = str; ISLOWER (*s) || *s == '.' || *s == '3'
|| *s == '2' || *s == '1'; ++s)
;
/* Must be at least one digit. */
case '#':
- if (isdigit (*s++))
+ if (ISDIGIT (*s++))
{
- while (isdigit (*s))
+ while (ISDIGIT (*s))
++s;
continue;
}
/* Any register r0..r31. */
case 'r':
s++;
- if (!isdigit (c = *s++))
+ if (!ISDIGIT (c = *s++))
{
goto error;
}
- if (isdigit (*s))
+ if (ISDIGIT (*s))
{
if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
goto error;
else
s++;
- if (*s++ == 'f' && isdigit (*s))
+ if (*s++ == 'f' && ISDIGIT (*s))
{
mask = *s++;
- if (isdigit (*s))
+ if (ISDIGIT (*s))
{
mask = 10 * (mask - '0') + (*s++ - '0');
if (mask >= 32)
the_insn.opcode = opcode;
}
-
static int
i860_get_expression (str)
char *str;
return 0;
}
-
/* Turn a string in input_line_pointer into a floating point constant of
type TYPE, and store the appropriate bytes in *LITP. The number of
LITTLENUMS emitted is stored in *SIZEP. An error message is returned,
LITTLENUM_TYPE words[MAX_LITTLENUMS];
LITTLENUM_TYPE *wordP;
char *t;
- char *atof_ieee ();
switch (type)
{
return 0;
}
-
/* Write out in current endian mode. */
void
md_number_to_chars (buf, val, n)
number_to_chars_littleendian (buf, val, n);
}
-
-/* This should never be called for i860. */
-void
-md_number_to_disp (buf, val, n)
- char *buf ATTRIBUTE_UNUSED;
- long val ATTRIBUTE_UNUSED;
- int n ATTRIBUTE_UNUSED;
-{
- as_fatal (_("md_number_to_disp\n"));
-}
-
-
-/* This should never be called for i860. */
-void
-md_number_to_field (buf, val, fix)
- char *buf ATTRIBUTE_UNUSED;
- long val ATTRIBUTE_UNUSED;
- void *fix ATTRIBUTE_UNUSED;
-{
- as_fatal (_("i860_number_to_field\n"));
-}
-
-
/* This should never be called for i860. */
int
md_estimate_size_before_relax (fragP, segtype)
as_fatal (_("i860_estimate_size_before_relax\n"));
}
-
#ifdef DEBUG_I860
static void
print_insn (insn)
}
#endif /* DEBUG_I860 */
-
\f
#ifdef OBJ_ELF
-CONST char *md_shortopts = "VQ:";
+const char *md_shortopts = "VQ:";
#else
-CONST char *md_shortopts = "";
+const char *md_shortopts = "";
#endif
-
#define OPTION_EB (OPTION_MD_BASE + 0)
#define OPTION_EL (OPTION_MD_BASE + 1)
#define OPTION_WARN_EXPAND (OPTION_MD_BASE + 2)
};
size_t md_longopts_size = sizeof (md_longopts);
-
int
md_parse_option (c, arg)
int c;
return 1;
}
-
void
md_show_usage (stream)
FILE *stream;
return 0;
}
-
/* The i860 denotes auto-increment with '++'. */
void
md_operand (exp)
}
}
-
/* Round up a section size to the appropriate boundary. */
valueT
md_section_align (segment, size)
return size;
}
-
/* On the i860, a PC-relative offset is relative to the address of the
of the offset plus its size. */
long
return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
}
-
/* Determine the relocation needed for non PC-relative 16-bit immediates.
Also adjust the given immediate as necessary. Finally, check that
all constraints (such as alignment) are satisfied. */
long *val;
{
valueT fup = fix->fx_addnumber;
- bfd_reloc_code_real_type reloc;
+ bfd_reloc_code_real_type reloc;
if (fix->fx_pcrel)
abort ();
return reloc;
}
-
/* Attempt to simplify or eliminate a fixup. To indicate that a fixup
has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
we will have to generate a reloc entry. */
-int
-md_apply_fix3 (fix, valuep, seg)
- fixS *fix;
- valueT *valuep;
+
+void
+md_apply_fix3 (fix, valP, seg)
+ fixS * fix;
+ valueT * valP;
segT seg ATTRIBUTE_UNUSED;
{
-
char *buf;
- long val = (long)(*valuep);
+ long val = *valP;
unsigned long insn;
valueT fup;
}
}
else if (fup & OP_IMM_U16)
- {
- abort ();
- }
+ abort ();
+
else if (fup & OP_IMM_SPLIT16)
{
fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
fix->fx_r_type = BFD_RELOC_NONE;
fix->fx_done = 1;
}
- }
+ }
else if (fup & OP_IMM_BR16)
{
if (val & 0x3)
}
else if (fup != OP_NONE)
{
- as_bad_where (fix->fx_file, fix->fx_line,
- _("Unrecognized fix-up (0x%08x)"), fup);
+ as_bad_where (fix->fx_file, fix->fx_line,
+ _("Unrecognized fix-up (0x%08lx)"), (unsigned long) fup);
abort ();
}
else
fix->fx_done = 1;
}
}
-
- /* Return value ignored. */
- return 0;
}
-
/* Generate a machine dependent reloc from a fixup. */
arelent*
tc_gen_reloc (section, fixp)
}
return reloc;
}
-