/* GAS interface for targets using CGEN: Cpu tools GENerator.
- Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#include <setjmp.h>
#include "ansidecl.h"
#include "bfd.h"
+#include "symcat.h"
#include "cgen-opc.h"
#include "as.h"
#include "subsegs.h"
/* Queue a fixup. */
-void
+static void
cgen_queue_fixup (opindex, opinfo, expP)
int opindex;
expressionS * expP;
{
/* We need to generate a fixup for this expression. */
if (num_fixups >= MAX_FIXUPS)
- as_fatal ("too many fixups");
+ as_fatal (_("too many fixups"));
fixups[num_fixups].exp = * expP;
fixups[num_fixups].opindex = opindex;
fixups[num_fixups].opinfo = opinfo;
++ num_fixups;
}
+/* The following three functions allow a backup of the fixup chain to be made,
+ and to have this backup be swapped with the current chain. This allows
+ certain ports, eg the m32r, to swap two instructions and swap their fixups
+ at the same time. */
+static struct fixup saved_fixups [MAX_FIXUPS];
+static int saved_num_fixups;
+
+void
+cgen_save_fixups ()
+{
+ saved_num_fixups = num_fixups;
+
+ memcpy (saved_fixups, fixups, sizeof (fixups[0]) * num_fixups);
+
+ num_fixups = 0;
+}
+
+void
+cgen_restore_fixups ()
+{
+ num_fixups = saved_num_fixups;
+
+ memcpy (fixups, saved_fixups, sizeof (fixups[0]) * num_fixups);
+
+ saved_num_fixups = 0;
+}
+
+void
+cgen_swap_fixups ()
+{
+ int tmp;
+ struct fixup tmp_fixup;
+
+ if (num_fixups == 0)
+ {
+ cgen_restore_fixups ();
+ }
+ else if (saved_num_fixups == 0)
+ {
+ cgen_save_fixups ();
+ }
+ else
+ {
+ tmp = saved_num_fixups;
+ saved_num_fixups = num_fixups;
+ num_fixups = tmp;
+
+ for (tmp = MAX_FIXUPS; tmp--;)
+ {
+ tmp_fixup = saved_fixups [tmp];
+ saved_fixups [tmp] = fixups [tmp];
+ fixups [tmp] = tmp_fixup;
+ }
+ }
+}
+
/* Default routine to record a fixup.
This is a cover function to fix_new.
It exists because we record INSN with the fixup.
switch (exp.X_op)
{
case O_illegal :
- errmsg = "illegal operand";
+ errmsg = _("illegal operand");
* resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
break;
case O_absent :
- errmsg = "missing operand";
+ errmsg = _("missing operand");
* resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
break;
case O_constant :
/* Finish assembling instruction INSN.
BUF contains what we've built up so far.
- LENGTH is the size of the insn in bits. */
+ LENGTH is the size of the insn in bits.
+ Returns the address of the buffer containing the assembled instruction,
+ in case the caller needs to modify it for some reason. */
-void
+char *
cgen_asm_finish_insn (insn, buf, length)
const CGEN_INSN * insn;
cgen_insn_t * buf;
/* ??? Target foo issues various warnings here, so one might want to provide
a hook here. However, our caller is defined in tc-foo.c so there
shouldn't be a need for a hook. */
-
+
/* Write out the instruction.
It is important to fetch enough space in one call to `frag_more'.
We use (f - frag_now->fr_literal) to compute where we are and we
/* Create a relaxable fragment for this instruction. */
old_frag = frag_now;
-
+
frag_var (rs_machine_dependent,
max_len - byte_len /* max chars */,
0 /* variable part already allocated */,
fixups[i].opinfo,
& fixups[i].exp);
}
+
+ return f;
}
/* Apply a fixup to the object code. This is called for all the
valueT * valueP;
segT seg;
{
- char * where = fixP->fx_frag->fr_literal + fixP->fx_where;
- valueT value;
+ char * where = fixP->fx_frag->fr_literal + fixP->fx_where;
+ valueT value;
/* FIXME FIXME FIXME: The value we are passed in *valuep includes
the symbol values. Since we are using BFD_ASSEMBLER, if we are
{
/* We don't actually support subtracting a symbol. */
as_bad_where (fixP->fx_file, fixP->fx_line,
- "expression too complex");
+ _("expression too complex"));
}
}
}
finish the job. Testing for pcrel is a temporary hack. */
|| fixP->fx_pcrel)
{
- /* This may seem like overkill, and using bfd_install_relocation or
- some such may be preferable, but this is simple. */
CGEN_FIELDS_BITSIZE (& fields) = CGEN_INSN_BITSIZE (insn);
CGEN_SYM (set_operand) (opindex, & value, & fields);
- errmsg = CGEN_SYM (validate_operand) (opindex, & fields);
+ errmsg = CGEN_SYM (insert_operand) (opindex, & fields, where);
if (errmsg)
as_warn_where (fixP->fx_file, fixP->fx_line, "%s\n", errmsg);
- CGEN_SYM (insert_operand) (opindex, & fields, where);
}
if (fixP->fx_done)
else
{
as_bad_where (fixP->fx_file, fixP->fx_line,
- "unresolved expression that must be resolved");
+ _("unresolved expression that must be resolved"));
fixP->fx_done = 1;
return 1;
}
if (reloc->howto == (reloc_howto_type *) NULL)
{
as_bad_where (fixP->fx_file, fixP->fx_line,
- "internal error: can't export reloc type %d (`%s')",
+ _("internal error: can't export reloc type %d (`%s')"),
fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
return NULL;
}