* itbl-parse.y: Fix indentation mistakes from indent program.
* itbl-lex.l: Fix indentation mistakes from indent program. * itbl-ops.h: Add include for ansidecl.h. Add PARAMS around function arguments. Add declaration for itbl_have_entries. * itbl-ops.c: Add PARAMS around function arguments. * Makefile.in: Add itbl build rules. Add dependancies for itbl files to mips target. * as.c: Add itbl support. Add new option "--insttbl" for dynamically extending instruction set. * as.h: Declare insttbl_file_name; the name of file defining extensions to the basic instruction set * configure.in, configure: Add itbl-parse.o, itbl-lex.o, and itbl-ops.o to extra_objects for mips configuration. Add include file link from itbl-cpu.h to config/itbl-${target_cpu_type}.h. * config/tc-mips.c: Allow copz instructions. Add notes for future additions to the itbl support. Add debug macros. (macro): Call itbl_assemble to assemble itbl instructions. See if an unknown register is specified in an itbl entry.
This commit is contained in:
parent
c7583da0b6
commit
efec4a282c
@ -1,3 +1,27 @@
|
||||
Sat Feb 22 21:25:00 1997 Dawn Perchik <dawn@cygnus.com>
|
||||
|
||||
* itbl-parse.y: Fix indentation mistakes from indent program.
|
||||
* itbl-lex.l: Fix indentation mistakes from indent program.
|
||||
* itbl-ops.h: Add include for ansidecl.h.
|
||||
Add PARAMS around function arguments.
|
||||
Add declaration for itbl_have_entries.
|
||||
* itbl-ops.c: Add PARAMS around function arguments.
|
||||
* Makefile.in: Add itbl build rules.
|
||||
Add dependancies for itbl files to mips target.
|
||||
* as.c: Add itbl support.
|
||||
Add new option "--insttbl" for dynamically extending instruction set.
|
||||
* as.h: Declare insttbl_file_name;
|
||||
the name of file defining extensions to the basic instruction set
|
||||
* configure.in, configure: Add itbl-parse.o, itbl-lex.o, and
|
||||
itbl-ops.o to extra_objects for mips configuration.
|
||||
Add include file link from itbl-cpu.h to
|
||||
config/itbl-${target_cpu_type}.h.
|
||||
* config/tc-mips.c: Allow copz instructions.
|
||||
Add notes for future additions to the itbl support.
|
||||
Add debug macros.
|
||||
(macro): Call itbl_assemble to assemble itbl instructions.
|
||||
See if an unknown register is specified in an itbl entry.
|
||||
|
||||
Sat Feb 22 20:53:01 1997 Fred Fish <fnf@cygnus.com>
|
||||
* doc/internals.texi (CPU backend): Fix typo in md_section_align
|
||||
description.
|
||||
|
@ -62,7 +62,7 @@ INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_XFORM = $(INSTALL) -t='$(program_transform_name)'
|
||||
INSTALL_XFORM1= $(INSTALL_XFORM) -b=.1
|
||||
|
||||
DISTSTUFF= make-gas.com m68k-parse.c
|
||||
DISTSTUFF= make-gas.com m68k-parse.c itbl-parse.y itbl-lex.l itbl-ops.c
|
||||
|
||||
AR = ar
|
||||
AR_FLAGS = qv
|
||||
@ -72,11 +72,11 @@ MAKEINFO = makeinfo
|
||||
TEXI2DVI = texi2dvi
|
||||
RANLIB = ranlib
|
||||
CC = @CC@
|
||||
CFLAGS = -g
|
||||
LDFLAGS =
|
||||
HLDFLAGS = @HLDFLAGS@
|
||||
HLDENV = @HLDENV@
|
||||
RPATH_ENVVAR = @RPATH_ENVVAR@
|
||||
CFLAGS = -g
|
||||
LDFLAGS =
|
||||
|
||||
MAKEOVERRIDES=
|
||||
|
||||
@ -107,6 +107,12 @@ RUNTEST = `if [ -f $${srcdir}/../dejagnu/runtest ] ; then \
|
||||
fi`
|
||||
RUNTESTFLAGS=
|
||||
|
||||
# use @target_cpu_type@ for refering to configured target name
|
||||
IT_HDRS=itbl-parse.h $(srcdir)/itbl-ops.h itbl-cpu.h
|
||||
IT_SRCS=itbl-parse.c itbl-lex.c $(srcdir)/itbl-ops.c
|
||||
IT_DEPS=$(srcdir)/itbl-parse.y $(srcdir)/itbl-lex.l $(srcdir)/config/itbl-@target_cpu_type@.h
|
||||
IT_OBJS=itbl-parse.o itbl-lex.o itbl-ops.o
|
||||
|
||||
# Lists of files for various purposes.
|
||||
|
||||
REAL_SOURCES = \
|
||||
@ -123,6 +129,7 @@ REAL_SOURCES = \
|
||||
$(srcdir)/hash.c \
|
||||
$(srcdir)/input-file.c \
|
||||
$(srcdir)/input-scrub.c \
|
||||
$(srcdir)/itbl-ops.c \
|
||||
$(srcdir)/literal.c \
|
||||
$(srcdir)/messages.c \
|
||||
$(srcdir)/output-file.c \
|
||||
@ -150,6 +157,7 @@ REAL_HEADERS = \
|
||||
$(srcdir)/frags.h \
|
||||
$(srcdir)/hash.h \
|
||||
$(srcdir)/input-file.h \
|
||||
$(srcdir)/itbl-ops.h \
|
||||
$(srcdir)/listing.h \
|
||||
$(srcdir)/tc.h \
|
||||
$(srcdir)/obj.h \
|
||||
@ -164,7 +172,8 @@ LINKED_HEADERS = \
|
||||
targ-env.h \
|
||||
targ-cpu.h \
|
||||
obj-format.h \
|
||||
atof-targ.h
|
||||
atof-targ.h \
|
||||
itbl-cpu.h
|
||||
|
||||
HEADERS = $(LINKED_HEADERS) $(REAL_HEADERS)
|
||||
|
||||
@ -259,7 +268,7 @@ as.new: $(OBJS) $(LIBDEPS)
|
||||
|
||||
$(OBJS): config.h as.h targ-env.h obj-format.h targ-cpu.h flonum.h expr.h \
|
||||
struc-symbol.h write.h frags.h hash.h read.h symbols.h tc.h obj.h \
|
||||
listing.h bignum.h $(srcdir)/../include/libiberty.h
|
||||
listing.h bignum.h $(IT_HDRS) $(srcdir)/../include/libiberty.h
|
||||
|
||||
gasp.new: $(GASPOBJS) ../libiberty/libiberty.a
|
||||
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o gasp.new $(GASPOBJS) ../libiberty/libiberty.a $(LOADLIBES)
|
||||
@ -345,7 +354,8 @@ TARG_CPU_DEP_i960 =
|
||||
TARG_CPU_DEP_m68k = $(srcdir)/../include/opcode/m68k.h \
|
||||
$(srcdir)/config/m68k-parse.h subsegs.h
|
||||
TARG_CPU_DEP_m88k = $(srcdir)/config/m88k-opcode.h subsegs.h
|
||||
TARG_CPU_DEP_mips = $(srcdir)/../include/opcode/mips.h subsegs.h
|
||||
TARG_CPU_DEP_mips = $(srcdir)/../include/opcode/mips.h subsegs.h \
|
||||
$(srcdir)/config/itbl-mips.h
|
||||
TARG_CPU_DEP_ns32k =
|
||||
TARG_CPU_DEP_ppc = subsegs.h
|
||||
TARG_CPU_DEP_sh = $(srcdir)/../opcodes/sh-opc.h subsegs.h
|
||||
@ -388,7 +398,7 @@ ecoff.o : ecoff.c ecoff.h \
|
||||
stabs.o : stabs.c subsegs.h $(srcdir)/../include/aout/stab_gnu.h
|
||||
atof-targ.o : atof-targ.c
|
||||
obj-format.o : obj-format.c
|
||||
targ-cpu.o : targ-cpu.c $(TARG_CPU_DEP_@target_cpu_type@)
|
||||
targ-cpu.o : targ-cpu.c $(TARG_CPU_DEP_@target_cpu_type@) $(IT_HDRS)
|
||||
|
||||
obj-elf.o : $(srcdir)/config/obj-elf.c
|
||||
$(CC) -c $(ALL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(srcdir)/config/obj-elf.c
|
||||
@ -407,6 +417,51 @@ m68k-parse.c: $(srcdir)/config/m68k-parse.y
|
||||
mv -f y.tab.c m68k-parse.c
|
||||
m68k-parse.o: m68k-parse.c $(srcdir)/config/m68k-parse.h
|
||||
|
||||
|
||||
# The instruction table specification lexical analyzer and parser.
|
||||
|
||||
itbl-cpu.h : $(srcdir)/config/itbl-@target_cpu_type@.h
|
||||
itbl-parse.h : $(srcdir)/itbl-parse.y
|
||||
itbl-parse.c : $(srcdir)/itbl-parse.y
|
||||
itbl-lex.c : $(srcdir)/itbl-lex.l
|
||||
|
||||
itbl-lex.c: $(srcdir)/itbl-lex.l
|
||||
$(LEX) $(LEXFLAGS) $(srcdir)/itbl-lex.l
|
||||
mv -f lex.yy.c itbl-lex.c
|
||||
|
||||
itbl-lex.o: itbl-lex.c
|
||||
$(CC) -Wall -c $(ALL_CFLAGS) $(CPPFLAGS) $(INCLUDES) itbl-lex.c
|
||||
|
||||
itbl-parse.c itbl-parse.h: $(srcdir)/itbl-parse.y
|
||||
$(YACC) -d $(YACCFLAGS) $(srcdir)/itbl-parse.y
|
||||
mv -f y.tab.c itbl-parse.c
|
||||
mv -f y.tab.h itbl-parse.h
|
||||
|
||||
itbl-parse.o: itbl-parse.c itbl-parse.h $(srcdir)/itbl-ops.h itbl-cpu.h
|
||||
$(CC) -Wall -c $(ALL_CFLAGS) $(CPPFLAGS) $(INCLUDES) itbl-parse.c
|
||||
|
||||
itbl-ops.o: $(srcdir)/itbl-ops.c \
|
||||
$(srcdir)/itbl-ops.h itbl-cpu.h itbl-parse.h
|
||||
$(CC) -c $(ALL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(srcdir)/itbl-ops.c
|
||||
|
||||
# stand-alone assembler & disassembler
|
||||
itbl-test-ops.o: $(srcdir)/itbl-ops.c \
|
||||
$(srcdir)/itbl-ops.h itbl-cpu.h itbl-parse.h
|
||||
$(CC) -o itbl-test-ops.o -DSTAND_ALONE -c $(ALL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(srcdir)/itbl-ops.c
|
||||
|
||||
itbl-test.o: $(srcdir)/itbl-test.c $(srcdir)/itbl-ops.h itbl-cpu.h
|
||||
$(CC) -c -DSTAND_ALONE $(ALL_CFLAGS) $(INCLUDES) $(srcdir)/itbl-test.c
|
||||
|
||||
IT_TEST_OBJS= itbl-parse.o itbl-lex.o itbl-test-ops.o
|
||||
itbl-test: $(IT_TEST_OBJS) itbl-test.o $(LIBDEPS)
|
||||
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o itbl-test itbl-test.o $(IT_TEST_OBJS) $(LIBS)
|
||||
|
||||
# target itbl definitions for configuring coprocessor itbl support.
|
||||
# configure should have taken care of this for us...
|
||||
itbl-cpu.h: $(srcdir)/config/itbl-@target_cpu_type@.h
|
||||
ln -s $(srcdir)/config/itbl-@target_cpu_type@.h itbl-cpu.h
|
||||
|
||||
|
||||
# Remake the info files.
|
||||
|
||||
doc: $(srcdir)/as.info
|
||||
@ -428,6 +483,7 @@ clean mostlyclean: clean-here
|
||||
|
||||
DISTCLEAN_HERE = config.status Makefile targ-env.h targ-cpu.h \
|
||||
targ-cpu.c obj-format.h obj-format.c atof-targ.c TAGS \
|
||||
atof-targ.h itbl-cpu.h \
|
||||
config-stamp config.h conf config.log config.cache .gdbinit \
|
||||
testsuite/Makefile testsuite/config.status
|
||||
|
||||
|
67
gas/as.c
67
gas/as.c
@ -1,5 +1,5 @@
|
||||
/* as.c - GAS main program.
|
||||
Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 1996
|
||||
Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 1997
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
@ -35,7 +35,6 @@
|
||||
*/
|
||||
|
||||
#include "ansidecl.h"
|
||||
#include "libiberty.h"
|
||||
|
||||
#define COMMON
|
||||
|
||||
@ -85,6 +84,16 @@ struct defsym_list
|
||||
};
|
||||
|
||||
static struct defsym_list *defsyms;
|
||||
|
||||
/* Keep a record of the itbl files we read in. */
|
||||
|
||||
struct itbl_file_list
|
||||
{
|
||||
struct itbl_file_list *next;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static struct itbl_file_list *itbl_files;
|
||||
|
||||
void
|
||||
print_version_id ()
|
||||
@ -134,6 +143,8 @@ Options:\n\
|
||||
--statistics print various measured statistics from execution\n\
|
||||
--version print assembler version number and exit\n\
|
||||
-W suppress warnings\n\
|
||||
-t,--itbl INSTTBL extend instruction set to include instrictions\n\
|
||||
matching the specifications defined in file INSTTBL\n\
|
||||
-w ignored\n\
|
||||
-X ignored\n\
|
||||
-Z generate object file even after errors\n");
|
||||
@ -267,6 +278,8 @@ parse_args (pargc, pargv)
|
||||
'v',
|
||||
#endif
|
||||
'w', 'X',
|
||||
/* New option for extending instruction set (see also --itbl below) */
|
||||
't',
|
||||
'\0'
|
||||
};
|
||||
struct option *longopts;
|
||||
@ -289,7 +302,15 @@ parse_args (pargc, pargv)
|
||||
#define OPTION_EMULATION (OPTION_STD_BASE + 6)
|
||||
{"emulation", required_argument, NULL, OPTION_EMULATION},
|
||||
#define OPTION_DEFSYM (OPTION_STD_BASE + 7)
|
||||
{"defsym", required_argument, NULL, OPTION_DEFSYM}
|
||||
{"defsym", required_argument, NULL, OPTION_DEFSYM},
|
||||
#define OPTION_INSTTBL (OPTION_STD_BASE + 8)
|
||||
/* New option for extending instruction set (see also -t above).
|
||||
* The "-t file" or "--itbl file" option extends the basic set
|
||||
* of valid instructions by reading "file", a text file containing
|
||||
* a list of instruction formats. The additional opcodes and their
|
||||
* formats are added to the built-in set of instructions, and
|
||||
* mnemonics for new registers may also be defined. */
|
||||
{"itbl", required_argument, NULL, OPTION_INSTTBL}
|
||||
};
|
||||
|
||||
/* Construct the option lists from the standard list and the
|
||||
@ -422,6 +443,32 @@ the GNU General Public License. This program has absolutely no warranty.\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case OPTION_INSTTBL:
|
||||
case 't':
|
||||
{
|
||||
/* optarg is the name of the file containing the instruction
|
||||
formats, opcodes, register names, etc. */
|
||||
struct itbl_file_list *n;
|
||||
|
||||
n = (struct itbl_file_list *) xmalloc (sizeof *n);
|
||||
n->next = itbl_files;
|
||||
n->name = optarg;
|
||||
itbl_files = n;
|
||||
|
||||
/* Parse the file and add the new instructions to our internal
|
||||
table. If multiple instruction tables are specified, the
|
||||
information from this table gets appended onto the existing
|
||||
internal table. */
|
||||
itbl_files->name = xstrdup (optarg);
|
||||
if (itbl_parse(itbl_files->name) != 0)
|
||||
{
|
||||
fprintf (stderr, "Failed to read instruction table %s\n",
|
||||
itbl_files->name);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'J':
|
||||
flag_signed_overflow_ok = 1;
|
||||
break;
|
||||
@ -543,6 +590,7 @@ main (argc, argv)
|
||||
|
||||
start_time = get_run_time ();
|
||||
|
||||
|
||||
if (debug_memory)
|
||||
{
|
||||
#ifdef BFD_ASSEMBLER
|
||||
@ -581,7 +629,7 @@ main (argc, argv)
|
||||
symbol_begin ();
|
||||
frag_init ();
|
||||
subsegs_begin ();
|
||||
parse_args (&argc, &argv);
|
||||
parse_args (&argc, &argv);
|
||||
read_begin ();
|
||||
input_scrub_begin ();
|
||||
expr_begin ();
|
||||
@ -614,6 +662,8 @@ main (argc, argv)
|
||||
tc_init_after_args ();
|
||||
#endif
|
||||
|
||||
itbl_init ();
|
||||
|
||||
/* Now that we have fully initialized, and have created the output
|
||||
file, define any symbols requested by --defsym command line
|
||||
arguments. */
|
||||
@ -639,8 +689,7 @@ main (argc, argv)
|
||||
#endif
|
||||
|
||||
if (seen_at_least_1_file ()
|
||||
&& !((had_warnings () && flag_always_generate_output)
|
||||
|| had_errors () > 0))
|
||||
&& (flag_always_generate_output || had_errors () == 0))
|
||||
keep_it = 1;
|
||||
else
|
||||
keep_it = 0;
|
||||
@ -659,6 +708,9 @@ main (argc, argv)
|
||||
output_file_close (out_file_name);
|
||||
#endif
|
||||
|
||||
if (had_errors () > 0 && ! flag_always_generate_output)
|
||||
keep_it = 0;
|
||||
|
||||
if (!keep_it)
|
||||
unlink (out_file_name);
|
||||
|
||||
@ -668,8 +720,7 @@ main (argc, argv)
|
||||
|
||||
/* Use xexit instead of return, because under VMS environments they
|
||||
may not place the same interpretation on the value given. */
|
||||
if ((had_warnings () && flag_always_generate_output)
|
||||
|| had_errors () > 0)
|
||||
if (had_errors () > 0)
|
||||
xexit (EXIT_FAILURE);
|
||||
xexit (EXIT_SUCCESS);
|
||||
}
|
||||
|
@ -36,6 +36,13 @@
|
||||
#endif
|
||||
|
||||
#include "opcode/mips.h"
|
||||
#include "itbl-ops.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(x) printf x
|
||||
#else
|
||||
#define DBG(x)
|
||||
#endif
|
||||
|
||||
#ifdef OBJ_MAYBE_ELF
|
||||
/* Clean up namespace so we can include obj-elf.h too. */
|
||||
@ -159,6 +166,7 @@ static int interlocks = -1;
|
||||
|
||||
/* As with "interlocks" this is used by hardware that has FP
|
||||
(co-processor) interlocks. */
|
||||
/* Itbl support may require additional care here. */
|
||||
static int cop_interlocks = -1;
|
||||
|
||||
/* MIPS PIC level. */
|
||||
@ -872,6 +880,7 @@ md_begin ()
|
||||
else
|
||||
interlocks = 0;
|
||||
|
||||
/* Itbl support may require additional care here. */
|
||||
if (mips_cpu == 4300)
|
||||
cop_interlocks = 1;
|
||||
else
|
||||
@ -1099,7 +1108,11 @@ md_assemble (str)
|
||||
if (mips16)
|
||||
mips16_ip (str, &insn);
|
||||
else
|
||||
{
|
||||
mips_ip (str, &insn);
|
||||
DBG(("returned from mips_ip(%s) insn_opcode = 0x%x\n",
|
||||
str, insn.insn_opcode));
|
||||
}
|
||||
|
||||
if (insn_error)
|
||||
{
|
||||
@ -1221,6 +1234,7 @@ reg_needs_delay (reg)
|
||||
delays delay the use of general register rt for one
|
||||
instruction on the r3000. The r6000 and r4000 use
|
||||
interlocks. */
|
||||
/* Itbl support may require additional care here. */
|
||||
know (prev_pinfo & INSN_WRITE_GPR_T);
|
||||
if (reg == ((prev_insn.insn_opcode >> OP_SH_RT) & OP_MASK_RT))
|
||||
return 1;
|
||||
@ -1314,6 +1328,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
delays delay the use of general register rt for one
|
||||
instruction on the r3000. The r6000 and r4000 use
|
||||
interlocks. */
|
||||
/* Itbl support may require additional care here. */
|
||||
know (prev_pinfo & INSN_WRITE_GPR_T);
|
||||
if (mips_optimize == 0
|
||||
|| insn_uses_reg (ip,
|
||||
@ -1343,6 +1358,9 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
knowledge of CP0 handling, and the coprocessors other
|
||||
than the floating point unit are not distinguished at
|
||||
all. */
|
||||
/* Itbl support may require additional care here. FIXME!
|
||||
Need to modify this to include knowledge about
|
||||
user specified delays! */
|
||||
if (prev_pinfo & INSN_WRITE_FPR_T)
|
||||
{
|
||||
if (mips_optimize == 0
|
||||
@ -1369,6 +1387,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
instruction may set the condition codes, and the
|
||||
current instruction uses them, we must insert two
|
||||
NOPS. */
|
||||
/* Itbl support may require additional care here. */
|
||||
if (mips_optimize == 0
|
||||
|| ((prev_pinfo & INSN_WRITE_COND_CODE)
|
||||
&& (pinfo & INSN_READ_COND_CODE)))
|
||||
@ -1387,6 +1406,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
(this means it is a floating point comparison
|
||||
instruction). If this instruction uses the condition
|
||||
codes, we need to insert a single NOP. */
|
||||
/* Itbl support may require additional care here. */
|
||||
if (mips_optimize == 0
|
||||
|| (pinfo & INSN_READ_COND_CODE))
|
||||
++nops;
|
||||
@ -1414,6 +1434,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
|
||||
/* If the previous instruction was in a noreorder section, then
|
||||
we don't want to insert the nop after all. */
|
||||
/* Itbl support may require additional care here. */
|
||||
if (prev_insn_unreordered)
|
||||
nops = 0;
|
||||
|
||||
@ -1675,7 +1696,10 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FR) & OP_MASK_FR);
|
||||
if (pinfo & INSN_COP)
|
||||
{
|
||||
/* We don't keep enough information to sort these cases out. */
|
||||
/* We don't keep enough information to sort these cases out.
|
||||
The itbl support does keep this information however, although
|
||||
we currently don't support itbl fprmats as part of the cop
|
||||
instruction. May want to add this support in the future. */
|
||||
}
|
||||
/* Never set the bit for $0, which is always zero. */
|
||||
mips_gprmask &=~ 1 << 0;
|
||||
@ -1776,6 +1800,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
|| (! mips16
|
||||
&& mips_isa < 4
|
||||
&& (prev_pinfo
|
||||
/* Itbl support may require additional care here. */
|
||||
& (INSN_LOAD_COPROC_DELAY
|
||||
| INSN_COPROC_MOVE_DELAY
|
||||
| INSN_WRITE_COND_CODE)))
|
||||
@ -1787,6 +1812,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
&& mips_isa < 2
|
||||
&& (prev_pinfo
|
||||
& (INSN_LOAD_MEMORY_DELAY
|
||||
/* Itbl support may require additional care here. */
|
||||
| INSN_COPROC_MEMORY_DELAY)))
|
||||
/* We can not swap with a branch instruction. */
|
||||
|| (prev_pinfo
|
||||
@ -1891,6 +1917,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
can not swap. */
|
||||
|| (! mips16
|
||||
&& mips_isa < 4
|
||||
/* Itbl support may require additional care here. */
|
||||
&& ((prev_prev_insn.insn_mo->pinfo & INSN_LOAD_COPROC_DELAY)
|
||||
|| (mips_isa < 2
|
||||
&& (prev_prev_insn.insn_mo->pinfo
|
||||
@ -2108,6 +2135,7 @@ mips_emit_delays (insns)
|
||||
& (INSN_LOAD_MEMORY_DELAY
|
||||
| INSN_COPROC_MEMORY_DELAY))))
|
||||
{
|
||||
/* Itbl support may require additional care here. */
|
||||
++nops;
|
||||
if ((! mips16
|
||||
&& mips_isa < 4
|
||||
@ -2129,6 +2157,7 @@ mips_emit_delays (insns)
|
||||
&& ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
|
||||
|| (prev_prev_insn.insn_mo->pinfo & INSN_READ_LO))))
|
||||
{
|
||||
/* Itbl support may require additional care here. */
|
||||
if (! prev_prev_insn_unreordered)
|
||||
++nops;
|
||||
}
|
||||
@ -4421,18 +4450,22 @@ macro (ip)
|
||||
goto ld;
|
||||
case M_LWC0_AB:
|
||||
s = "lwc0";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto ld;
|
||||
case M_LWC1_AB:
|
||||
s = "lwc1";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto ld;
|
||||
case M_LWC2_AB:
|
||||
s = "lwc2";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto ld;
|
||||
case M_LWC3_AB:
|
||||
s = "lwc3";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto ld;
|
||||
case M_LWL_AB:
|
||||
@ -4445,14 +4478,17 @@ macro (ip)
|
||||
goto ld;
|
||||
case M_LDC1_AB:
|
||||
s = "ldc1";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto ld;
|
||||
case M_LDC2_AB:
|
||||
s = "ldc2";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto ld;
|
||||
case M_LDC3_AB:
|
||||
s = "ldc3";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto ld;
|
||||
case M_LDL_AB:
|
||||
@ -4494,18 +4530,22 @@ macro (ip)
|
||||
goto st;
|
||||
case M_SWC0_AB:
|
||||
s = "swc0";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto st;
|
||||
case M_SWC1_AB:
|
||||
s = "swc1";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto st;
|
||||
case M_SWC2_AB:
|
||||
s = "swc2";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto st;
|
||||
case M_SWC3_AB:
|
||||
s = "swc3";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto st;
|
||||
case M_SWL_AB:
|
||||
@ -4523,13 +4563,16 @@ macro (ip)
|
||||
case M_SDC1_AB:
|
||||
s = "sdc1";
|
||||
coproc = 1;
|
||||
/* Itbl support may require additional care here. */
|
||||
goto st;
|
||||
case M_SDC2_AB:
|
||||
s = "sdc2";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto st;
|
||||
case M_SDC3_AB:
|
||||
s = "sdc3";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto st;
|
||||
case M_SDL_AB:
|
||||
@ -4541,6 +4584,7 @@ macro (ip)
|
||||
tempreg = AT;
|
||||
used_at = 1;
|
||||
ld_st:
|
||||
/* Itbl support may require additional care here. */
|
||||
if (mask == M_LWC1_AB
|
||||
|| mask == M_SWC1_AB
|
||||
|| mask == M_LDC1_AB
|
||||
@ -4939,6 +4983,7 @@ macro (ip)
|
||||
* But, the resulting address is the same after relocation so why
|
||||
* generate the extra instruction?
|
||||
*/
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
if (mips_isa >= 2)
|
||||
{
|
||||
@ -4959,6 +5004,7 @@ macro (ip)
|
||||
|
||||
s = "swc1";
|
||||
fmt = "T,o(b)";
|
||||
/* Itbl support may require additional care here. */
|
||||
coproc = 1;
|
||||
goto ldd_std;
|
||||
|
||||
@ -4994,6 +5040,7 @@ macro (ip)
|
||||
/* Even on a big endian machine $fn comes before $fn+1. We have
|
||||
to adjust when loading from memory. We set coproc if we must
|
||||
load $fn+1 first. */
|
||||
/* Itbl support may require additional care here. */
|
||||
if (! target_big_endian)
|
||||
coproc = 0;
|
||||
|
||||
@ -5042,6 +5089,7 @@ macro (ip)
|
||||
used_at = 1;
|
||||
}
|
||||
|
||||
/* Itbl support may require additional care here. */
|
||||
macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
|
||||
coproc ? treg + 1 : treg,
|
||||
(int) BFD_RELOC_MIPS_GPREL, tempreg);
|
||||
@ -5051,6 +5099,7 @@ macro (ip)
|
||||
undesired nop. */
|
||||
hold_mips_optimize = mips_optimize;
|
||||
mips_optimize = 2;
|
||||
/* Itbl support may require additional care here. */
|
||||
macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
|
||||
coproc ? treg : treg + 1,
|
||||
(int) BFD_RELOC_MIPS_GPREL, tempreg);
|
||||
@ -5084,6 +5133,7 @@ macro (ip)
|
||||
if (p != NULL)
|
||||
p += 4;
|
||||
}
|
||||
/* Itbl support may require additional care here. */
|
||||
macro_build (p, &icnt, &offset_expr, s, fmt,
|
||||
coproc ? treg + 1 : treg,
|
||||
(int) BFD_RELOC_LO16, AT);
|
||||
@ -5091,6 +5141,7 @@ macro (ip)
|
||||
p += 4;
|
||||
/* FIXME: How do we handle overflow here? */
|
||||
offset_expr.X_add_number += 4;
|
||||
/* Itbl support may require additional care here. */
|
||||
macro_build (p, &icnt, &offset_expr, s, fmt,
|
||||
coproc ? treg : treg + 1,
|
||||
(int) BFD_RELOC_LO16, AT);
|
||||
@ -5131,6 +5182,7 @@ macro (ip)
|
||||
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
|
||||
mips_isa < 3 ? "addu" : "daddu",
|
||||
"d,v,t", AT, breg, AT);
|
||||
/* Itbl support may require additional care here. */
|
||||
macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
|
||||
coproc ? treg + 1 : treg,
|
||||
(int) BFD_RELOC_LO16, AT);
|
||||
@ -5140,6 +5192,7 @@ macro (ip)
|
||||
nop. */
|
||||
hold_mips_optimize = mips_optimize;
|
||||
mips_optimize = 2;
|
||||
/* Itbl support may require additional care here. */
|
||||
macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
|
||||
coproc ? treg : treg + 1,
|
||||
(int) BFD_RELOC_LO16, AT);
|
||||
@ -5197,6 +5250,7 @@ macro (ip)
|
||||
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
|
||||
mips_isa < 3 ? "addu" : "daddu",
|
||||
"d,v,t", AT, breg, AT);
|
||||
/* Itbl support may require additional care here. */
|
||||
macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
|
||||
coproc ? treg + 1 : treg,
|
||||
(int) BFD_RELOC_LO16, AT);
|
||||
@ -5206,6 +5260,7 @@ macro (ip)
|
||||
nop. */
|
||||
hold_mips_optimize = mips_optimize;
|
||||
mips_optimize = 2;
|
||||
/* Itbl support may require additional care here. */
|
||||
macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
|
||||
coproc ? treg : treg + 1,
|
||||
(int) BFD_RELOC_LO16, AT);
|
||||
@ -5235,6 +5290,7 @@ macro (ip)
|
||||
"d,v,t", AT, breg, AT);
|
||||
p += 4;
|
||||
}
|
||||
/* Itbl support may require additional care here. */
|
||||
macro_build (p, &icnt, &expr1, s, fmt,
|
||||
coproc ? treg + 1 : treg,
|
||||
(int) BFD_RELOC_LO16, AT);
|
||||
@ -5245,6 +5301,7 @@ macro (ip)
|
||||
nop. */
|
||||
hold_mips_optimize = mips_optimize;
|
||||
mips_optimize = 2;
|
||||
/* Itbl support may require additional care here. */
|
||||
macro_build (p, &icnt, &expr1, s, fmt,
|
||||
coproc ? treg : treg + 1,
|
||||
(int) BFD_RELOC_LO16, AT);
|
||||
@ -5274,10 +5331,12 @@ macro (ip)
|
||||
used_at = 1;
|
||||
}
|
||||
|
||||
/* Itbl support may require additional care here. */
|
||||
macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
|
||||
coproc ? treg + 1 : treg,
|
||||
(int) BFD_RELOC_MIPS_GPREL, tempreg);
|
||||
offset_expr.X_add_number += 4;
|
||||
/* Itbl support may require additional care here. */
|
||||
macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
|
||||
coproc ? treg : treg + 1,
|
||||
(int) BFD_RELOC_MIPS_GPREL, tempreg);
|
||||
@ -5303,8 +5362,59 @@ macro (ip)
|
||||
macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg + 1,
|
||||
(int) BFD_RELOC_LO16, breg);
|
||||
return;
|
||||
|
||||
/* New code added to support COPZ instructions.
|
||||
This code builds table entries out of the macros in mip_opcodes.
|
||||
R4000 uses interlocks to handle coproc delays.
|
||||
Other chips (like the R3000) require nops to be inserted for delays.
|
||||
|
||||
FIXME: Currently, we require that the user handle delays.
|
||||
In order to fill delay slots for non-interlocked chips,
|
||||
we must have a way to specify delays based on the coprocessor.
|
||||
Eg. 4 cycles if load coproc reg from memory, 1 if in cache, etc.
|
||||
What are the side-effects of the cop instruction?
|
||||
What cache support might we have and what are its effects?
|
||||
Both coprocessor & memory require delays. how long???
|
||||
What registers are read/set/modified?
|
||||
|
||||
If an itbl is provided to interpret cop instructions,
|
||||
this knowledge can be encoded in the itbl spec. */
|
||||
|
||||
case M_COP0:
|
||||
s = "cop0";
|
||||
goto copz;
|
||||
case M_COP1:
|
||||
s = "cop1";
|
||||
goto copz;
|
||||
case M_COP2:
|
||||
s = "cop2";
|
||||
goto copz;
|
||||
case M_COP3:
|
||||
s = "cop3";
|
||||
copz:
|
||||
/* For now we just do C (same as Cz). */
|
||||
macro_build ((char *) NULL, &icnt, &offset_expr, s, "C");
|
||||
return;
|
||||
|
||||
#ifdef LOSING_COMPILER
|
||||
default:
|
||||
/* Try and see if this is a new itbl instruction.
|
||||
This code builds table entries out of the macros in mip_opcodes.
|
||||
FIXME: For now we just assemble the expression and pass it's
|
||||
value along as a 32-bit immediate.
|
||||
We may want to have the assembler assemble this value,
|
||||
so that we gain the assembler's knowledge of delay slots,
|
||||
symbols, etc.
|
||||
Would it be more efficient to use mask (id) here? */
|
||||
if (itbl_have_entries
|
||||
&& immed_expr = itbl_assemble(ip->insn_mo->name, ""), immed_expr)
|
||||
{
|
||||
s = ip->insn_mo->name;
|
||||
s2 = "cop3";
|
||||
coproc = ITBL_DECODE_PNUM(immed_expr);;
|
||||
macro_build ((char *) NULL, &icnt, &immed_expr, s, "C");
|
||||
return;
|
||||
}
|
||||
macro2 (ip);
|
||||
return;
|
||||
}
|
||||
@ -5967,6 +6077,8 @@ macro2 (ip)
|
||||
break;
|
||||
|
||||
default:
|
||||
/* FIXME: Check if this is one of the itbl macros, since they are
|
||||
added dynamically. */
|
||||
as_bad ("Macro %s not implemented yet", ip->insn_mo->name);
|
||||
break;
|
||||
}
|
||||
@ -6485,6 +6597,30 @@ mips_ip (str, ip)
|
||||
s += 4;
|
||||
regno = KT1;
|
||||
}
|
||||
else if (itbl_have_entries)
|
||||
{
|
||||
char *p, *n;
|
||||
int r;
|
||||
|
||||
p = s+1; /* advance past '$' */
|
||||
n = itbl_get_field(&p); /* n is name */
|
||||
|
||||
/* See if this is a register defined in an
|
||||
itbl entry */
|
||||
if (r = itbl_get_reg_val(n), r)
|
||||
{
|
||||
/* Get_field advances to the start of the next
|
||||
field, so we need to back rack to the end of
|
||||
the last field. */
|
||||
if (p)
|
||||
s = p-1;
|
||||
else
|
||||
s = strchr(s,'\0');
|
||||
regno = r;
|
||||
}
|
||||
else
|
||||
goto notreg;
|
||||
}
|
||||
else
|
||||
goto notreg;
|
||||
}
|
||||
@ -6508,6 +6644,9 @@ mips_ip (str, ip)
|
||||
/* 'z' only matches $0. */
|
||||
if (c == 'z' && regno != 0)
|
||||
break;
|
||||
|
||||
/* Now that we have assembled one operand, we use the args string
|
||||
* to figure out where it goes in the instruction. */
|
||||
switch (c)
|
||||
{
|
||||
case 'r':
|
||||
@ -6540,6 +6679,11 @@ mips_ip (str, ip)
|
||||
is $0. This only matches $0, and is checked
|
||||
outside the switch. */
|
||||
break;
|
||||
case 'D':
|
||||
/* Itbl operand; not yet implemented. FIXME ?? */
|
||||
break;
|
||||
/* What about all other operands like 'i',
|
||||
which can be specified in the opcode table? */
|
||||
}
|
||||
lastregno = regno;
|
||||
continue;
|
||||
@ -8309,6 +8453,19 @@ MIPS options:\n\
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mips_init_after_args ()
|
||||
{
|
||||
if (itbl_have_entries)
|
||||
{
|
||||
/* initialize opcodes */
|
||||
bfd_mips_num_opcodes = bfd_mips_num_builtin_opcodes;
|
||||
mips_opcodes = (struct mips_opcode*) mips_builtin_opcodes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
long
|
||||
md_pcrel_from (fixP)
|
||||
fixS *fixP;
|
||||
|
25
gas/configure
vendored
25
gas/configure
vendored
@ -1017,6 +1017,8 @@ EOF
|
||||
;;
|
||||
esac
|
||||
|
||||
# additional parsers based on cpu-type
|
||||
|
||||
case ${cpu_type} in
|
||||
m68k)
|
||||
case ${extra_objects} in
|
||||
@ -1024,6 +1026,27 @@ EOF
|
||||
*) extra_objects="$extra_objects m68k-parse.o" ;;
|
||||
esac
|
||||
;;
|
||||
|
||||
mips)
|
||||
echo ${extra_objects} | grep -s "itbl-parse.o"
|
||||
if test $? -ne 0 ; then
|
||||
extra_objects="$extra_objects itbl-parse.o"
|
||||
fi
|
||||
|
||||
echo ${extra_objects} | grep -s "itbl-lex.o"
|
||||
if test $? -ne 0 ; then
|
||||
extra_objects="$extra_objects itbl-lex.o"
|
||||
fi
|
||||
|
||||
echo ${extra_objects} | grep -s "itbl-ops.o"
|
||||
if test $? -ne 0 ; then
|
||||
extra_objects="$extra_objects itbl-ops.o"
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# See if we really can support this configuration with the emulation code.
|
||||
@ -1267,8 +1290,10 @@ EOF
|
||||
files="config/tc-${target_cpu_type}.c config/tc-${target_cpu_type}.h \
|
||||
config/obj-${obj_format}.h config/obj-${obj_format}.c \
|
||||
config/te-${te_file}.h config/atof-${atof}.c \
|
||||
config/itbl-${target_cpu_type}.h \
|
||||
$extra_files"
|
||||
links="targ-cpu.c targ-cpu.h obj-format.h obj-format.c targ-env.h atof-targ.c \
|
||||
itbl-cpu.h \
|
||||
$extra_links"
|
||||
|
||||
case ${primary_bfd_gas}-${target_cpu_type}-${obj_format} in
|
||||
|
@ -365,6 +365,26 @@ changequote([,])dnl
|
||||
*) extra_objects="$extra_objects m68k-parse.o" ;;
|
||||
esac
|
||||
;;
|
||||
|
||||
mips)
|
||||
`echo ${extra_objects}` | grep -s "itbl-parse.o"
|
||||
if test $? -ne 0 ; then
|
||||
extra_objects="$extra_objects itbl-parse.o"
|
||||
fi
|
||||
|
||||
`echo ${extra_objects}` | grep -s "itbl-lex.o"
|
||||
if test $? -ne 0 ; then
|
||||
extra_objects="$extra_objects itbl-lex.o"
|
||||
fi
|
||||
|
||||
`echo ${extra_objects}` | grep -s "itbl-ops.o"
|
||||
if test $? -ne 0 ; then
|
||||
extra_objects="$extra_objects itbl-ops.o"
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
# See if we really can support this configuration with the emulation code.
|
||||
@ -527,8 +547,10 @@ AC_DEFINE_UNQUOTED(DEFAULT_EMULATION, "$DEFAULT_EMULATION")
|
||||
files="config/tc-${target_cpu_type}.c config/tc-${target_cpu_type}.h \
|
||||
config/obj-${obj_format}.h config/obj-${obj_format}.c \
|
||||
config/te-${te_file}.h config/atof-${atof}.c \
|
||||
config/itbl-${target_cpu_type}.h \
|
||||
$extra_files"
|
||||
links="targ-cpu.c targ-cpu.h obj-format.h obj-format.c targ-env.h atof-targ.c \
|
||||
itbl-cpu.h \
|
||||
$extra_links"
|
||||
|
||||
case ${primary_bfd_gas}-${target_cpu_type}-${obj_format} in
|
||||
|
138
gas/itbl-lex.l
138
gas/itbl-lex.l
@ -1,3 +1,25 @@
|
||||
|
||||
/* itbl-lex.l
|
||||
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
|
||||
GAS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GAS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GAS; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
%{
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -23,64 +45,70 @@ HEX [0-9A-Fa-f]
|
||||
|
||||
%%
|
||||
|
||||
"creg"|"CREG" {
|
||||
return CREG;
|
||||
}
|
||||
"dreg"|"DREG" {
|
||||
return DREG;
|
||||
}
|
||||
"greg"|"GREG" {
|
||||
return GREG;
|
||||
}
|
||||
"immed"|"IMMED" {
|
||||
return IMMED;
|
||||
}
|
||||
"addr"|"ADDR" {
|
||||
return ADDR;
|
||||
}
|
||||
"insn"|"INSN" {
|
||||
return INSN;
|
||||
}
|
||||
"creg"|"CREG" {
|
||||
return CREG;
|
||||
}
|
||||
"dreg"|"DREG" {
|
||||
return DREG;
|
||||
}
|
||||
"greg"|"GREG" {
|
||||
return GREG;
|
||||
}
|
||||
"immed"|"IMMED" {
|
||||
return IMMED;
|
||||
}
|
||||
"addr"|"ADDR" {
|
||||
return ADDR;
|
||||
}
|
||||
"insn"|"INSN" {
|
||||
return INSN;
|
||||
}
|
||||
"p"{DIGIT} {
|
||||
yytext[yyleng]=0;
|
||||
yylval.processor = strtoul(yytext+1,0,0);
|
||||
return PNUM;
|
||||
}
|
||||
{DIGIT}+ {
|
||||
yytext[yyleng]=0;
|
||||
yylval.num = strtoul(yytext,0,0);
|
||||
return NUM;
|
||||
}
|
||||
"0x"{HEX}+ {
|
||||
yytext[yyleng]=0;
|
||||
yylval.num = strtoul(yytext,0,0);
|
||||
return NUM;
|
||||
}
|
||||
yytext[yyleng] = 0;
|
||||
yylval.processor = strtoul (yytext+1, 0, 0);
|
||||
return PNUM;
|
||||
}
|
||||
{DIGIT}+ {
|
||||
yytext[yyleng] = 0;
|
||||
yylval.num = strtoul (yytext, 0, 0);
|
||||
return NUM;
|
||||
}
|
||||
"0x"{HEX}+ {
|
||||
yytext[yyleng] = 0;
|
||||
yylval.num = strtoul (yytext, 0, 0);
|
||||
return NUM;
|
||||
}
|
||||
{ALPHA}{ALNUM}* {
|
||||
yytext[yyleng]=0;
|
||||
yylval.str = strdup(yytext);
|
||||
return ID;
|
||||
}
|
||||
yytext[yyleng] = 0;
|
||||
yylval.str = strdup (yytext);
|
||||
return ID;
|
||||
}
|
||||
";"|"#" {
|
||||
int c;
|
||||
while ((c = input()) != EOF) {
|
||||
if (c == '\n')
|
||||
{
|
||||
unput(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
int c;
|
||||
while ((c = input ()) != EOF)
|
||||
{
|
||||
if (c == '\n')
|
||||
{
|
||||
unput (c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
"\n" {
|
||||
insntbl_line++;
|
||||
MDBG(("in lex, NL=%d (x%x)\n",NL,NL));
|
||||
return NL;
|
||||
}
|
||||
" "|"\t" { }
|
||||
. {
|
||||
MDBG(("char=%x,%d\n",yytext[0],yytext[0]));
|
||||
return yytext[0];
|
||||
}
|
||||
insntbl_line++;
|
||||
MDBG (("in lex, NL = %d (x%x)\n", NL, NL));
|
||||
return NL;
|
||||
}
|
||||
" "|"\t" {
|
||||
}
|
||||
. {
|
||||
MDBG (("char = %x, %d\n", yytext[0], yytext[0]));
|
||||
return yytext[0];
|
||||
}
|
||||
%%
|
||||
|
||||
int yywrap() { return 1; }
|
||||
int
|
||||
yywrap ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
1110
gas/itbl-ops.c
1110
gas/itbl-ops.c
File diff suppressed because it is too large
Load Diff
@ -1,18 +1,40 @@
|
||||
|
||||
/* itbl-ops.h
|
||||
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
|
||||
GAS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GAS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GAS; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
/* External functions, constants and defines for itbl support */
|
||||
|
||||
#include "ansidecl.h"
|
||||
#include "itbl-cpu.h"
|
||||
|
||||
/* Defaults for definitions required by generic code */
|
||||
/* Defaults for definitions required by generic code */
|
||||
#ifndef ITBL_NUMBER_OF_PROCESSORS
|
||||
#define ITBL_NUMBER_OF_PROCESSORS 1
|
||||
#endif
|
||||
|
||||
#ifndef ITBL_MAX_BITPOS
|
||||
#ifndef ITBL_MAX_BITPOS
|
||||
#define ITBL_MAX_BITPOS 31
|
||||
#endif
|
||||
|
||||
#ifndef ITBL_TYPE
|
||||
#ifndef ITBL_TYPE
|
||||
#define ITBL_TYPE unsigned long
|
||||
#endif
|
||||
|
||||
@ -31,45 +53,50 @@
|
||||
typedef ITBL_TYPE t_insn;
|
||||
|
||||
/* types of entries */
|
||||
typedef enum
|
||||
{
|
||||
typedef enum
|
||||
{
|
||||
e_insn,
|
||||
e_dreg,
|
||||
e_regtype0 = e_dreg,
|
||||
e_regtype0 = e_dreg,
|
||||
e_creg,
|
||||
e_greg,
|
||||
e_addr,
|
||||
e_nregtypes = e_greg+1,
|
||||
e_nregtypes = e_greg + 1,
|
||||
e_immed,
|
||||
e_ntypes,
|
||||
e_invtype /* invalid type */
|
||||
} e_type;
|
||||
e_invtype /* invalid type */
|
||||
} e_type;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typedef enum
|
||||
{
|
||||
e_p0,
|
||||
e_nprocs=NUMBER_OF_PROCESSORS,
|
||||
e_invproc /* invalid processor */
|
||||
} e_processor;
|
||||
e_nprocs = NUMBER_OF_PROCESSORS,
|
||||
e_invproc /* invalid processor */
|
||||
} e_processor;
|
||||
|
||||
/* 0 means an instruction table was not specified. */
|
||||
extern int itbl_have_entries;
|
||||
|
||||
/* These routines are visible to the main part of the assembler */
|
||||
|
||||
int itbl_parse(char* insntbl);
|
||||
void itbl_init(void);
|
||||
char *itbl_get_field(char **s);
|
||||
unsigned long itbl_assemble(char *name, char *operands);
|
||||
int itbl_disassemble(char *str, unsigned long insn);
|
||||
int itbl_parse(char *tbl); /* parses insn tbl */
|
||||
unsigned long itbl_get_reg_val(char *name);
|
||||
unsigned long itbl_get_val(e_processor processor, e_type type, char *name);
|
||||
char *itbl_get_name(e_processor processor, e_type type, unsigned long val);
|
||||
int itbl_parse PARAMS ((char *insntbl));
|
||||
void itbl_init PARAMS ((void));
|
||||
char *itbl_get_field PARAMS ((char **s));
|
||||
unsigned long itbl_assemble PARAMS ((char *name, char *operands));
|
||||
int itbl_disassemble PARAMS ((char *str, unsigned long insn));
|
||||
int itbl_parse PARAMS ((char *tbl)); /* parses insn tbl */
|
||||
unsigned long itbl_get_reg_val PARAMS ((char *name));
|
||||
unsigned long itbl_get_val PARAMS ((e_processor processor, e_type type,
|
||||
char *name));
|
||||
char *itbl_get_name PARAMS ((e_processor processor, e_type type,
|
||||
unsigned long val));
|
||||
|
||||
/* These routines are called by the table parser used to build the
|
||||
* dynamic list of new processor instructions and registers. */
|
||||
|
||||
struct itbl_entry *itbl_add_reg(int yyproc, int yytype, char *regname, int regnum);
|
||||
struct itbl_entry *itbl_add_insn(int yyproc, char *name, unsigned long value,
|
||||
int sbit, int ebit, unsigned long flags);
|
||||
struct itbl_field *itbl_add_operand(struct itbl_entry *e, int yytype,
|
||||
int sbit, int ebit, unsigned long flags);
|
||||
/* These routines are called by the table parser used to build the
|
||||
dynamic list of new processor instructions and registers. */
|
||||
|
||||
struct itbl_entry *itbl_add_reg PARAMS ((int yyproc, int yytype,
|
||||
char *regname, int regnum));
|
||||
struct itbl_entry *itbl_add_insn PARAMS ((int yyproc, char *name,
|
||||
unsigned long value, int sbit, int ebit, unsigned long flags));
|
||||
struct itbl_field *itbl_add_operand PARAMS ((struct itbl_entry * e, int yytype,
|
||||
int sbit, int ebit, unsigned long flags));
|
||||
|
424
gas/itbl-parse.y
424
gas/itbl-parse.y
@ -1,4 +1,27 @@
|
||||
|
||||
/* itbl-parse.y
|
||||
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
|
||||
GAS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GAS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GAS; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
%{
|
||||
|
||||
/*
|
||||
|
||||
Yacc grammar for instruction table entries.
|
||||
@ -6,8 +29,8 @@ Yacc grammar for instruction table entries.
|
||||
=======================================================================
|
||||
Original Instruction table specification document:
|
||||
|
||||
MIPS Coprocessor Table Specification
|
||||
====================================
|
||||
MIPS Coprocessor Table Specification
|
||||
====================================
|
||||
|
||||
This document describes the format of the MIPS coprocessor table. The
|
||||
table specifies a list of valid functions, data registers and control
|
||||
@ -31,9 +54,9 @@ complete name of the table, including path and extension.
|
||||
|
||||
Examples:
|
||||
|
||||
gas -t cop.tbl test.s -o test.o
|
||||
gas -t /usr/local/lib/cop.tbl test.s -o test.o
|
||||
gas --itbl d:\gnu\data\cop.tbl test.s -o test.o
|
||||
gas -t cop.tbl test.s -o test.o
|
||||
gas -t /usr/local/lib/cop.tbl test.s -o test.o
|
||||
gas --itbl d:\gnu\data\cop.tbl test.s -o test.o
|
||||
|
||||
Only one table may be supplied during a single invocation of
|
||||
the assembler.
|
||||
@ -46,30 +69,37 @@ Below is a list of the valid coprocessor instruction classes for
|
||||
any given coprocessor "z". These instructions are already recognized
|
||||
by the assembler, and are listed here only for reference.
|
||||
|
||||
Class format instructions
|
||||
Class format instructions
|
||||
-------------------------------------------------
|
||||
Class1: op base rt offset
|
||||
LWCz rt,offset(base)
|
||||
SWCz rt,offset(base)
|
||||
Class2: COPz sub rt rd 0
|
||||
MTCz rt,rd
|
||||
MFCz rt,rd
|
||||
CTCz rt,rd
|
||||
CFCz rt,rd
|
||||
Class3: COPz CO cofun
|
||||
COPz cofun
|
||||
Class4: COPz BC br offset
|
||||
BCzT offset
|
||||
BCzF offset
|
||||
Class5: COPz sub rt rd 0
|
||||
DMFCz rt,rd
|
||||
DMTCz rt,rd
|
||||
Class6: op base rt offset
|
||||
LDCz rt,offset(base)
|
||||
SDCz rt,offset(base)
|
||||
Class7: COPz BC br offset
|
||||
BCzTL offset
|
||||
BCzFL offset
|
||||
Class1:
|
||||
op base rt offset
|
||||
LWCz rt,offset (base)
|
||||
SWCz rt,offset (base)
|
||||
Class2:
|
||||
COPz sub rt rd 0
|
||||
MTCz rt,rd
|
||||
MFCz rt,rd
|
||||
CTCz rt,rd
|
||||
CFCz rt,rd
|
||||
Class3:
|
||||
COPz CO cofun
|
||||
COPz cofun
|
||||
Class4:
|
||||
COPz BC br offset
|
||||
BCzT offset
|
||||
BCzF offset
|
||||
Class5:
|
||||
COPz sub rt rd 0
|
||||
DMFCz rt,rd
|
||||
DMTCz rt,rd
|
||||
Class6:
|
||||
op base rt offset
|
||||
LDCz rt,offset (base)
|
||||
SDCz rt,offset (base)
|
||||
Class7:
|
||||
COPz BC br offset
|
||||
BCzTL offset
|
||||
BCzFL offset
|
||||
|
||||
The coprocessor table defines coprocessor-specific registers that can
|
||||
be used with all of the above classes of instructions, where
|
||||
@ -90,41 +120,41 @@ Table Grammar
|
||||
|
||||
Here is the grammar for the coprocessor table:
|
||||
|
||||
table -> entry*
|
||||
table -> entry*
|
||||
|
||||
entry -> [z entrydef] [comment] '\n'
|
||||
entry -> [z entrydef] [comment] '\n'
|
||||
|
||||
entrydef -> type name val
|
||||
entrydef -> 'insn' name val funcdef ; type of entry (instruction)
|
||||
entrydef -> type name val
|
||||
entrydef -> 'insn' name val funcdef ; type of entry (instruction)
|
||||
|
||||
z -> 'p'['0'..'3'] ; processor number
|
||||
type -> ['dreg' | 'creg' | 'greg' ] ; type of entry (register)
|
||||
z -> 'p'['0'..'3'] ; processor number
|
||||
type -> ['dreg' | 'creg' | 'greg' ] ; type of entry (register)
|
||||
; 'dreg', 'creg' or 'greg' specifies a data, control, or general
|
||||
; register mnemonic, respectively
|
||||
name -> [ltr|dec]* ; mnemonic of register/function
|
||||
val -> [dec|hex] ; register/function number (integer constant)
|
||||
; register mnemonic, respectively
|
||||
name -> [ltr|dec]* ; mnemonic of register/function
|
||||
val -> [dec|hex] ; register/function number (integer constant)
|
||||
|
||||
funcdef -> frange flags fields
|
||||
; bitfield range for opcode
|
||||
; list of fields' formats
|
||||
fields -> field*
|
||||
field -> [','] ftype frange flags
|
||||
flags -> ['*' flagexpr]
|
||||
flagexpr -> '[' flagexpr ']'
|
||||
flagexpr -> val '|' flagexpr
|
||||
ftype -> [ type | 'immed' | 'addr' ]
|
||||
funcdef -> frange flags fields
|
||||
; bitfield range for opcode
|
||||
; list of fields' formats
|
||||
fields -> field*
|
||||
field -> [','] ftype frange flags
|
||||
flags -> ['*' flagexpr]
|
||||
flagexpr -> '[' flagexpr ']'
|
||||
flagexpr -> val '|' flagexpr
|
||||
ftype -> [ type | 'immed' | 'addr' ]
|
||||
; 'immed' specifies an immediate value; see grammar for "val" above
|
||||
; 'addr' specifies a C identifier; name of symbol to be resolved at
|
||||
; link time
|
||||
frange -> ':' val '-' val ; starting to ending bit positions, where
|
||||
; where 0 is least significant bit
|
||||
frange -> (null) ; default range of 31-0 will be assumed
|
||||
; 'addr' specifies a C identifier; name of symbol to be resolved at
|
||||
; link time
|
||||
frange -> ':' val '-' val ; starting to ending bit positions, where
|
||||
; where 0 is least significant bit
|
||||
frange -> (null) ; default range of 31-0 will be assumed
|
||||
|
||||
comment -> [';'|'#'] [char]*
|
||||
char -> any printable character
|
||||
ltr -> ['a'..'z'|'A'..'Z']
|
||||
dec -> ['0'..'9']* ; value in decimal
|
||||
hex -> '0x'['0'..'9' | 'a'..'f' | 'A'..'F']* ; value in hexidecimal
|
||||
comment -> [';'|'#'] [char]*
|
||||
char -> any printable character
|
||||
ltr -> ['a'..'z'|'A'..'Z']
|
||||
dec -> ['0'..'9']* ; value in decimal
|
||||
hex -> '0x'['0'..'9' | 'a'..'f' | 'A'..'F']* ; value in hexidecimal
|
||||
|
||||
|
||||
Examples
|
||||
@ -134,15 +164,15 @@ Example 1:
|
||||
|
||||
The table:
|
||||
|
||||
p1 dreg d1 1 ; data register "d1" for COP1 has value 1
|
||||
p1 creg c3 3 ; ctrl register "c3" for COP1 has value 3
|
||||
p3 func fill 0x1f:24-20 ; function "fill" for COP3 has value 31 and
|
||||
; no fields
|
||||
p1 dreg d1 1 ; data register "d1" for COP1 has value 1
|
||||
p1 creg c3 3 ; ctrl register "c3" for COP1 has value 3
|
||||
p3 func fill 0x1f:24-20 ; function "fill" for COP3 has value 31 and
|
||||
; no fields
|
||||
|
||||
will allow the assembler to accept the following coprocessor instructions:
|
||||
|
||||
LWC1 d1,0x100($2)
|
||||
fill
|
||||
LWC1 d1,0x100 ($2)
|
||||
fill
|
||||
|
||||
Here, the general purpose register "$2", and instruction "LWC1", are standard
|
||||
mnemonics built-in to the MIPS assembler.
|
||||
@ -152,46 +182,46 @@ Example 2:
|
||||
|
||||
The table:
|
||||
|
||||
p3 dreg d3 3 ; data register "d3" for COP3 has value 3
|
||||
p3 creg c2 22 ; control register "c2" for COP3 has value 22
|
||||
p3 func fee 0x1f:24-20 dreg:17-13 creg:12-8 immed:7-0
|
||||
; function "fee" for COP3 has value 31, and 3 fields
|
||||
; consisting of a data register, a control register,
|
||||
; and an immediate value.
|
||||
p3 dreg d3 3 ; data register "d3" for COP3 has value 3
|
||||
p3 creg c2 22 ; control register "c2" for COP3 has value 22
|
||||
p3 func fee 0x1f:24-20 dreg:17-13 creg:12-8 immed:7-0
|
||||
; function "fee" for COP3 has value 31, and 3 fields
|
||||
; consisting of a data register, a control register,
|
||||
; and an immediate value.
|
||||
|
||||
will allow the assembler to accept the following coprocessor instruction:
|
||||
|
||||
fee d3,c2,0x1
|
||||
fee d3,c2,0x1
|
||||
|
||||
and will emit the object code:
|
||||
|
||||
31-26 25 24-20 19-18 17-13 12-8 7-0
|
||||
COPz CO fun dreg creg immed
|
||||
010011 1 11111 00 00011 10110 00000001
|
||||
31-26 25 24-20 19-18 17-13 12-8 7-0
|
||||
COPz CO fun dreg creg immed
|
||||
010011 1 11111 00 00011 10110 00000001
|
||||
|
||||
0x4ff07601
|
||||
0x4ff07601
|
||||
|
||||
|
||||
Example 3:
|
||||
|
||||
The table:
|
||||
|
||||
p3 dreg d3 3 ; data register "d3" for COP3 has value 3
|
||||
p3 creg c2 22 ; control register "c2" for COP3 has value 22
|
||||
p3 func fuu 0x01f00001 dreg:17-13 creg:12-8
|
||||
p3 dreg d3 3 ; data register "d3" for COP3 has value 3
|
||||
p3 creg c2 22 ; control register "c2" for COP3 has value 22
|
||||
p3 func fuu 0x01f00001 dreg:17-13 creg:12-8
|
||||
|
||||
will allow the assembler to accept the following coprocessor
|
||||
instruction:
|
||||
|
||||
fuu d3,c2
|
||||
fuu d3,c2
|
||||
|
||||
and will emit the object code:
|
||||
|
||||
31-26 25 24-20 19-18 17-13 12-8 7-0
|
||||
COPz CO fun dreg creg
|
||||
010011 1 11111 00 00011 10110 00000001
|
||||
31-26 25 24-20 19-18 17-13 12-8 7-0
|
||||
COPz CO fun dreg creg
|
||||
010011 1 11111 00 00011 10110 00000001
|
||||
|
||||
0x4ff07601
|
||||
0x4ff07601
|
||||
|
||||
In this way, the programmer can force arbitrary bits of an instruction
|
||||
to have predefined values.
|
||||
@ -205,7 +235,8 @@ use 0s to mask out the ranges which don't apply.
|
||||
May decide to modify the syntax to allow commas separate multiple
|
||||
ranges within an instruction (range','range).
|
||||
|
||||
Changes in grammar: The number of parms argument to the function entry
|
||||
Changes in grammar:
|
||||
The number of parms argument to the function entry
|
||||
was deleted from the original format such that we now count the fields.
|
||||
|
||||
----
|
||||
@ -245,169 +276,184 @@ FIXME! hex is ambiguous with any digit
|
||||
static int sbit, ebit;
|
||||
static struct itbl_entry *insn=0;
|
||||
extern int insntbl_line;
|
||||
int yyparse(void);
|
||||
int yylex(void);
|
||||
int yyparse (void);
|
||||
int yylex (void);
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
%union
|
||||
{
|
||||
char *str;
|
||||
int num;
|
||||
int processor;
|
||||
unsigned long val;
|
||||
}
|
||||
}
|
||||
|
||||
%token DREG CREG GREG IMMED ADDR INSN NUM ID NL PNUM
|
||||
%type <val> value flags flagexpr
|
||||
%type <num> number NUM ftype regtype pnum PNUM
|
||||
%type <str> ID name
|
||||
%token DREG CREG GREG IMMED ADDR INSN NUM ID NL PNUM
|
||||
%type <val> value flags flagexpr
|
||||
%type <num> number NUM ftype regtype pnum PNUM
|
||||
%type <str> ID name
|
||||
|
||||
%start insntbl
|
||||
|
||||
%%
|
||||
|
||||
insntbl: entrys
|
||||
insntbl:
|
||||
entrys
|
||||
;
|
||||
|
||||
entrys: entry entrys
|
||||
entrys:
|
||||
entry entrys
|
||||
|
|
||||
;
|
||||
|
||||
entry: pnum regtype name value NL
|
||||
{
|
||||
DBG(("line %d: entry pnum=%d type=%d name=%s value=x%x\n",
|
||||
insntbl_line, $1, $2, $3, $4));
|
||||
itbl_add_reg($1, $2, $3, $4);
|
||||
}
|
||||
entry:
|
||||
pnum regtype name value NL
|
||||
{
|
||||
DBG (("line %d: entry pnum=%d type=%d name=%s value=x%x\n",
|
||||
insntbl_line, $1, $2, $3, $4));
|
||||
itbl_add_reg ($1, $2, $3, $4);
|
||||
}
|
||||
| pnum INSN name value range flags
|
||||
{
|
||||
DBG(("line %d: entry pnum=%d type=INSN name=%s value=x%x",
|
||||
insntbl_line, $1, $3, $4));
|
||||
DBG((" sbit=%d ebit=%d flags=0x%x\n", sbit, ebit, $6));
|
||||
insn=itbl_add_insn($1, $3, $4, sbit, ebit, $6);
|
||||
}
|
||||
{
|
||||
DBG (("line %d: entry pnum=%d type=INSN name=%s value=x%x",
|
||||
insntbl_line, $1, $3, $4));
|
||||
DBG ((" sbit=%d ebit=%d flags=0x%x\n", sbit, ebit, $6));
|
||||
insn=itbl_add_insn ($1, $3, $4, sbit, ebit, $6);
|
||||
}
|
||||
fieldspecs NL
|
||||
| NL
|
||||
| error NL
|
||||
;
|
||||
|
||||
fieldspecs: ',' fieldspec fieldspecs
|
||||
fieldspecs:
|
||||
',' fieldspec fieldspecs
|
||||
| fieldspec fieldspecs
|
||||
|
|
||||
;
|
||||
|
||||
ftype: regtype
|
||||
{
|
||||
DBGL2(("ftype\n"));
|
||||
$$ = $1;
|
||||
}
|
||||
ftype:
|
||||
regtype
|
||||
{
|
||||
DBGL2 (("ftype\n"));
|
||||
$$ = $1;
|
||||
}
|
||||
| ADDR
|
||||
{
|
||||
DBGL2(("addr\n"));
|
||||
$$ = ADDR;
|
||||
}
|
||||
{
|
||||
DBGL2 (("addr\n"));
|
||||
$$ = ADDR;
|
||||
}
|
||||
| IMMED
|
||||
{
|
||||
DBGL2(("immed\n"));
|
||||
$$ = IMMED;
|
||||
}
|
||||
{
|
||||
DBGL2 (("immed\n"));
|
||||
$$ = IMMED;
|
||||
}
|
||||
;
|
||||
|
||||
fieldspec: ftype range flags
|
||||
{
|
||||
DBG(("line %d: field type=%d sbit=%d ebit=%d, flags=0x%x\n",
|
||||
insntbl_line, $1, sbit, ebit, $3));
|
||||
itbl_add_operand(insn, $1, sbit, ebit, $3);
|
||||
}
|
||||
fieldspec:
|
||||
ftype range flags
|
||||
{
|
||||
DBG (("line %d: field type=%d sbit=%d ebit=%d, flags=0x%x\n",
|
||||
insntbl_line, $1, sbit, ebit, $3));
|
||||
itbl_add_operand (insn, $1, sbit, ebit, $3);
|
||||
}
|
||||
;
|
||||
|
||||
flagexpr: NUM '|' flagexpr
|
||||
{
|
||||
$$ = $1 | $3;
|
||||
}
|
||||
flagexpr:
|
||||
NUM '|' flagexpr
|
||||
{
|
||||
$$ = $1 | $3;
|
||||
}
|
||||
| '[' flagexpr ']'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
| NUM
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
flags: '*' flagexpr
|
||||
{
|
||||
DBGL2(("flags=%d\n", $2));
|
||||
$$ = $2;
|
||||
}
|
||||
flags:
|
||||
'*' flagexpr
|
||||
{
|
||||
DBGL2 (("flags=%d\n", $2));
|
||||
$$ = $2;
|
||||
}
|
||||
|
|
||||
{
|
||||
$$ = 0;
|
||||
}
|
||||
{
|
||||
$$ = 0;
|
||||
}
|
||||
;
|
||||
|
||||
range: ':' NUM '-' NUM
|
||||
{
|
||||
DBGL2(("range %d %d\n", $2, $4));
|
||||
sbit = $2;
|
||||
ebit = $4;
|
||||
}
|
||||
range:
|
||||
':' NUM '-' NUM
|
||||
{
|
||||
DBGL2 (("range %d %d\n", $2, $4));
|
||||
sbit = $2;
|
||||
ebit = $4;
|
||||
}
|
||||
|
|
||||
{
|
||||
sbit = 31;
|
||||
ebit = 0;
|
||||
}
|
||||
{
|
||||
sbit = 31;
|
||||
ebit = 0;
|
||||
}
|
||||
;
|
||||
|
||||
pnum: PNUM
|
||||
{
|
||||
DBGL2(("pnum=%d\n",$1));
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
pnum:
|
||||
PNUM
|
||||
{
|
||||
DBGL2 (("pnum=%d\n",$1));
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
regtype: DREG
|
||||
{
|
||||
DBGL2(("dreg\n"));
|
||||
$$ = DREG;
|
||||
}
|
||||
regtype:
|
||||
DREG
|
||||
{
|
||||
DBGL2 (("dreg\n"));
|
||||
$$ = DREG;
|
||||
}
|
||||
| CREG
|
||||
{
|
||||
DBGL2(("creg\n"));
|
||||
$$ = CREG;
|
||||
}
|
||||
{
|
||||
DBGL2 (("creg\n"));
|
||||
$$ = CREG;
|
||||
}
|
||||
| GREG
|
||||
{
|
||||
DBGL2(("greg\n"));
|
||||
$$ = GREG;
|
||||
}
|
||||
{
|
||||
DBGL2 (("greg\n"));
|
||||
$$ = GREG;
|
||||
}
|
||||
;
|
||||
|
||||
name: ID
|
||||
{
|
||||
DBGL2(("name=%s\n",$1));
|
||||
$$ = $1;
|
||||
}
|
||||
name:
|
||||
ID
|
||||
{
|
||||
DBGL2 (("name=%s\n",$1));
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
number: NUM
|
||||
{
|
||||
DBGL2(("num=%d\n",$1));
|
||||
$$ = $1;
|
||||
}
|
||||
number:
|
||||
NUM
|
||||
{
|
||||
DBGL2 (("num=%d\n",$1));
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
value: NUM
|
||||
{
|
||||
DBGL2(("val=x%x\n",$1));
|
||||
$$ = $1;
|
||||
}
|
||||
value:
|
||||
NUM
|
||||
{
|
||||
DBGL2 (("val=x%x\n",$1));
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
%%
|
||||
|
||||
void yyerror(char *msg)
|
||||
void
|
||||
yyerror (char *msg)
|
||||
{
|
||||
printf("line %d: %s\n", insntbl_line, msg);
|
||||
printf ("line %d: %s\n", insntbl_line, msg);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user