Add openRISC support in opcodes

This commit is contained in:
Nick Clifton 2001-04-27 13:34:20 +00:00
parent 015a42b4cf
commit 87e6d78217
20 changed files with 4506 additions and 304 deletions

View File

@ -1,3 +1,7 @@
2001-04-27 Johan Rydberg <jrydberg@opencores.org>
* NEWS: Announce support for OpenRISC.
2001-04-17 Danny Smith <dannysmith@users.sourceforge.net>
* dlltool.c (do_default_excludes): Initialise to true.

View File

@ -1,5 +1,7 @@
-*- text -*-
* Support for OpenRISC by Johan Rydberg.
* New command line switch to objcopy -B (or --binary-architecture) which sets
the archiceture of the output file to the given argument. This option only
makes sense, if the input target is binary. Otherwise it is ignored.

View File

@ -1,3 +1,7 @@
2001-04-27 Johan Rydberg <jrydberg@opencores.org>
* dis-asm.h (print_insn_openrisc): Add prototype.
2001-04-15 Daniel Berlin <dan@cgsoftware.com>
* ternary.h: New file - Ternary search tree header.

View File

@ -210,6 +210,7 @@ extern int print_insn_mcore PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_mn10200 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_mn10300 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_ns32k PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_openrisc PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_pdp11 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_big_powerpc PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_little_powerpc PARAMS ((bfd_vma, disassemble_info*));

View File

@ -1,3 +1,21 @@
2001-04-27 Johan Rydberg <jrydberg@opencores.org>
* Makefile.am: Add OpenRISC target.
* Makefile.in: Regenerated.
* disassemble.c (disassembler): Recognize the OpenRISC disassembly.
* configure.in (bfd_openrisc_arch): Add target.
* configure: Regenerated.
* openrisc-asm.c: New file.
* openrisc-desc.c: Likewise.
* openrisc-desc.h: Likewise.
* openrisc-dis.c: Likewise.
* openrisc-ibld.c: Likewise.
* openrisc-opc.c: Likewise.
* openrisc-opc.h: Likewise.
2001-04-24 Christian Groessler <cpg@aladdin.de>
* z8k-dis.c: add names of control registers (ctrl_names);

View File

@ -26,6 +26,7 @@ HFILES = \
h8500-opc.h \
m32r-desc.h m32r-opc.h \
mcore-opc.h \
openrisc-desc.h openrisc-opc.h \
sh-opc.h \
sysdep.h \
ia64-asmtab.h \
@ -97,6 +98,11 @@ CFILES = \
m10300-dis.c \
m10300-opc.c \
ns32k-dis.c \
openrisc-asm.c \
openrisc-desc.c \
openrisc-dis.c \
openrisc-ibld.c \
openrisc-opc.c \
pdp11-dis.c \
pdp11-opc.c \
pj-dis.c \
@ -173,6 +179,11 @@ ALL_MACHINES = \
mips-opc.lo \
mips16-opc.lo \
ns32k-dis.lo \
openrisc-asm.lo \
openrisc-desc.lo \
openrisc-dis.lo \
openrisc-ibld.lo \
openrisc-opc.lo \
pdp11-dis.lo \
pdp11-opc.lo \
pj-dis.lo \
@ -236,7 +247,7 @@ config.status: $(srcdir)/configure $(srcdir)/../bfd/configure.in
$(SHELL) ./config.status --recheck
CLEANFILES = \
stamp-m32r stamp-fr30 \
stamp-m32r stamp-fr30 stamp-openrisc \
libopcodes.a stamp-lib dep.sed DEP DEPA DEP1 DEP2
@ -254,9 +265,11 @@ CGENDEPS = ../cgen/stamp-cgen \
if CGEN_MAINT
M32R_DEPS = stamp-m32r
FR30_DEPS = stamp-fr30
OPENRISC_DEPS = stamp-openrisc
else
M32R_DEPS =
FR30_DEPS =
OPENRISC_DEPS =
endif
run-cgen:
@ -277,6 +290,11 @@ $(srcdir)/fr30-desc.h $(srcdir)/fr30-desc.c $(srcdir)/fr30-opc.h $(srcdir)/fr30-
stamp-fr30: $(CGENDEPS) $(CGENDIR)/fr30.cpu $(CGENDIR)/fr30.opc
$(MAKE) run-cgen arch=fr30 prefix=fr30 options= extrafiles=
$(srcdir)/openrisc-desc.h $(srcdir)/openrisc-desc.c $(srcdir)/openrisc-opc.h $(srcdir)/openrisc-opc.c $(srcdir)/openrisc-ibld.c $(srcdir)/openrisc-asm.c $(srcdir)/openrisc-dis.c: $(OPENRISC_DEPS)
@true
stamp-openrisc: $(CGENDEPS) $(CGENDIR)/openrisc.cpu $(CGENDIR)/openrisc.opc
$(MAKE) run-cgen arch=openrisc prefix=openrisc options= extrafiles=
ia64-gen: ia64-gen.o
$(LINK) ia64-gen.o $(LIBIBERTY)
@ -480,6 +498,21 @@ m10300-opc.lo: m10300-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
ns32k-dis.lo: ns32k-dis.c $(BFD_H) $(INCDIR)/ansidecl.h \
sysdep.h config.h $(INCDIR)/dis-asm.h $(INCDIR)/opcode/ns32k.h \
opintl.h
openrisc-asm.lo: openrisc-asm.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(BFD_H) $(INCDIR)/symcat.h openrisc-desc.h $(INCDIR)/opcode/cgen.h \
openrisc-opc.h opintl.h
openrisc-desc.lo: openrisc-desc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(BFD_H) $(INCDIR)/symcat.h openrisc-desc.h $(INCDIR)/opcode/cgen.h \
openrisc-opc.h opintl.h $(INCDIR)/libiberty.h
openrisc-dis.lo: openrisc-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h openrisc-desc.h \
$(INCDIR)/opcode/cgen.h openrisc-opc.h opintl.h
openrisc-ibld.lo: openrisc-ibld.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h openrisc-desc.h \
$(INCDIR)/opcode/cgen.h openrisc-opc.h opintl.h
openrisc-opc.lo: openrisc-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(BFD_H) $(INCDIR)/symcat.h openrisc-desc.h $(INCDIR)/opcode/cgen.h \
openrisc-opc.h $(INCDIR)/libiberty.h
pdp11-dis.lo: pdp11-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
$(INCDIR)/ansidecl.h $(INCDIR)/opcode/pdp11.h
pdp11-opc.lo: pdp11-opc.c $(INCDIR)/opcode/pdp11.h

View File

@ -136,6 +136,7 @@ HFILES = \
h8500-opc.h \
m32r-desc.h m32r-opc.h \
mcore-opc.h \
openrisc-desc.h openrisc-opc.h \
sh-opc.h \
sysdep.h \
ia64-asmtab.h \
@ -208,6 +209,11 @@ CFILES = \
m10300-dis.c \
m10300-opc.c \
ns32k-dis.c \
openrisc-asm.c \
openrisc-desc.c \
openrisc-dis.c \
openrisc-ibld.c \
openrisc-opc.c \
pdp11-dis.c \
pdp11-opc.c \
pj-dis.c \
@ -285,6 +291,11 @@ ALL_MACHINES = \
mips-opc.lo \
mips16-opc.lo \
ns32k-dis.lo \
openrisc-asm.lo \
openrisc-desc.lo \
openrisc-dis.lo \
openrisc-ibld.lo \
openrisc-opc.lo \
pdp11-dis.lo \
pdp11-opc.lo \
pj-dis.lo \
@ -327,7 +338,7 @@ noinst_LIBRARIES = libopcodes.a
POTFILES = $(HFILES) $(CFILES)
CLEANFILES = \
stamp-m32r stamp-fr30 \
stamp-m32r stamp-fr30 stamp-openrisc \
libopcodes.a stamp-lib dep.sed DEP DEPA DEP1 DEP2
@ -346,6 +357,8 @@ CGENDEPS = ../cgen/stamp-cgen \
@CGEN_MAINT_FALSE@M32R_DEPS =
@CGEN_MAINT_TRUE@FR30_DEPS = @CGEN_MAINT_TRUE@stamp-fr30
@CGEN_MAINT_FALSE@FR30_DEPS =
@CGEN_MAINT_TRUE@OPENRISC_DEPS = @CGEN_MAINT_TRUE@stamp-openrisc
@CGEN_MAINT_FALSE@OPENRISC_DEPS =
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = config.h
@ -788,6 +801,11 @@ $(srcdir)/fr30-desc.h $(srcdir)/fr30-desc.c $(srcdir)/fr30-opc.h $(srcdir)/fr30-
stamp-fr30: $(CGENDEPS) $(CGENDIR)/fr30.cpu $(CGENDIR)/fr30.opc
$(MAKE) run-cgen arch=fr30 prefix=fr30 options= extrafiles=
$(srcdir)/openrisc-desc.h $(srcdir)/openrisc-desc.c $(srcdir)/openrisc-opc.h $(srcdir)/openrisc-opc.c $(srcdir)/openrisc-ibld.c $(srcdir)/openrisc-asm.c $(srcdir)/openrisc-dis.c: $(OPENRISC_DEPS)
@true
stamp-openrisc: $(CGENDEPS) $(CGENDIR)/openrisc.cpu $(CGENDIR)/openrisc.opc
$(MAKE) run-cgen arch=openrisc prefix=openrisc options= extrafiles=
ia64-gen: ia64-gen.o
$(LINK) ia64-gen.o $(LIBIBERTY)
@ -991,6 +1009,21 @@ m10300-opc.lo: m10300-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
ns32k-dis.lo: ns32k-dis.c $(BFD_H) $(INCDIR)/ansidecl.h \
sysdep.h config.h $(INCDIR)/dis-asm.h $(INCDIR)/opcode/ns32k.h \
opintl.h
openrisc-asm.lo: openrisc-asm.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(BFD_H) $(INCDIR)/symcat.h openrisc-desc.h $(INCDIR)/opcode/cgen.h \
openrisc-opc.h opintl.h
openrisc-desc.lo: openrisc-desc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(BFD_H) $(INCDIR)/symcat.h openrisc-desc.h $(INCDIR)/opcode/cgen.h \
openrisc-opc.h opintl.h $(INCDIR)/libiberty.h
openrisc-dis.lo: openrisc-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h openrisc-desc.h \
$(INCDIR)/opcode/cgen.h openrisc-opc.h opintl.h
openrisc-ibld.lo: openrisc-ibld.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h openrisc-desc.h \
$(INCDIR)/opcode/cgen.h openrisc-opc.h opintl.h
openrisc-opc.lo: openrisc-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(BFD_H) $(INCDIR)/symcat.h openrisc-desc.h $(INCDIR)/opcode/cgen.h \
openrisc-opc.h $(INCDIR)/libiberty.h
pdp11-dis.lo: pdp11-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
$(INCDIR)/ansidecl.h $(INCDIR)/opcode/pdp11.h
pdp11-opc.lo: pdp11-opc.c $(INCDIR)/opcode/pdp11.h

View File

@ -1,135 +1,132 @@
/* config.in. Generated automatically from configure.in by autoheader. */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
#undef CRAY_STACKSEG_END
/* Define if using `alloca.c'. */
/* Define if using alloca.c. */
#undef C_ALLOCA
/* Define to 1 if NLS is requested */
#undef ENABLE_NLS
/* Define to empty if the keyword does not work. */
#undef const
/* Define if you have `alloca', as a function or macro. */
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
This function is required for alloca.c support on those systems. */
#undef CRAY_STACKSEG_END
/* Define if you have alloca, as a function or macro. */
#undef HAVE_ALLOCA
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
#undef HAVE_ALLOCA_H
/* Define if you have the <argz.h> header file. */
#undef HAVE_ARGZ_H
/* Define if you have the `dcgettext' function. */
#undef HAVE_DCGETTEXT
/* Define if you have the `getcwd' function. */
#undef HAVE_GETCWD
/* Define if you have the `getpagesize' function. */
#undef HAVE_GETPAGESIZE
/* Define as 1 if you have gettext and don't want to use GNU gettext. */
#undef HAVE_GETTEXT
/* Define if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define if your locale.h file contains LC_MESSAGES. */
#undef HAVE_LC_MESSAGES
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define if you have a working `mmap' system call. */
/* Define if you have a working `mmap' system call. */
#undef HAVE_MMAP
/* Define if you have the `munmap' function. */
#undef HAVE_MUNMAP
/* Define as __inline if that's what the C compiler calls it. */
#undef inline
/* Define if you have the <nl_types.h> header file. */
#undef HAVE_NL_TYPES_H
/* Define to `long' if <sys/types.h> doesn't define. */
#undef off_t
/* Define if you have the `putenv' function. */
#undef HAVE_PUTENV
/* Define if you have the `setenv' function. */
#undef HAVE_SETENV
/* Define if you have the `setlocale' function. */
#undef HAVE_SETLOCALE
/* Define if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define if you have the stpcpy function */
#undef HAVE_STPCPY
/* Define if you have the `strcasecmp' function. */
#undef HAVE_STRCASECMP
/* Define if you have the `strchr' function. */
#undef HAVE_STRCHR
/* Define if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the <values.h> header file. */
#undef HAVE_VALUES_H
/* Define if you have the `__argz_count' function. */
#undef HAVE___ARGZ_COUNT
/* Define if you have the `__argz_next' function. */
#undef HAVE___ARGZ_NEXT
/* Define if you have the `__argz_stringify' function. */
#undef HAVE___ARGZ_STRINGIFY
/* Name of package */
#undef PACKAGE
/* Define to `unsigned' if <sys/types.h> doesn't define. */
#undef size_t
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown
*/
#undef STACK_DIRECTION
/* Define if you have the ANSI C header files. */
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define if you have the __argz_count function. */
#undef HAVE___ARGZ_COUNT
/* Define if you have the __argz_next function. */
#undef HAVE___ARGZ_NEXT
/* Define if you have the __argz_stringify function. */
#undef HAVE___ARGZ_STRINGIFY
/* Define if you have the dcgettext function. */
#undef HAVE_DCGETTEXT
/* Define if you have the getcwd function. */
#undef HAVE_GETCWD
/* Define if you have the getpagesize function. */
#undef HAVE_GETPAGESIZE
/* Define if you have the munmap function. */
#undef HAVE_MUNMAP
/* Define if you have the putenv function. */
#undef HAVE_PUTENV
/* Define if you have the setenv function. */
#undef HAVE_SETENV
/* Define if you have the setlocale function. */
#undef HAVE_SETLOCALE
/* Define if you have the stpcpy function. */
#undef HAVE_STPCPY
/* Define if you have the strcasecmp function. */
#undef HAVE_STRCASECMP
/* Define if you have the strchr function. */
#undef HAVE_STRCHR
/* Define if you have the <argz.h> header file. */
#undef HAVE_ARGZ_H
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define if you have the <nl_types.h> header file. */
#undef HAVE_NL_TYPES_H
/* Define if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the <values.h> header file. */
#undef HAVE_VALUES_H
/* Name of package */
#undef PACKAGE
/* Version number of package */
#undef VERSION
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define if you have the stpcpy function */
#undef HAVE_STPCPY
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
if it is not supported. */
#undef inline
/* Define if your locale.h file contains LC_MESSAGES. */
#undef HAVE_LC_MESSAGES
/* Define to `long' if <sys/types.h> does not define. */
#undef off_t
/* Define to 1 if NLS is requested */
#undef ENABLE_NLS
/* Define as 1 if you have gettext and don't want to use GNU gettext. */
#undef HAVE_GETTEXT
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t

371
opcodes/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -195,6 +195,7 @@ if test x${all_targets} = xfalse ; then
bfd_mn10200_arch) ta="$ta m10200-dis.lo m10200-opc.lo" ;;
bfd_mn10300_arch) ta="$ta m10300-dis.lo m10300-opc.lo" ;;
bfd_ns32k_arch) ta="$ta ns32k-dis.lo" ;;
bfd_openrisc_arch) ta="$ta openrisc-asm.lo openrisc-desc.lo openrisc-dis.lo openrisc-ibld.lo openrisc-opc.lo" using_cgen=yes ;;
bfd_pdp11_arch) ta="$ta pdp11-dis.lo pdp11-opc.lo" ;;
bfd_pj_arch) ta="$ta pj-dis.lo pj-opc.lo" ;;
bfd_powerpc_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;

View File

@ -47,6 +47,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define ARCH_mn10200
#define ARCH_mn10300
#define ARCH_ns32k
#define ARCH_openrisc
#define ARCH_pdp11
#define ARCH_pj
#define ARCH_powerpc
@ -226,6 +227,11 @@ disassembler (abfd)
disassemble = print_insn_mn10300;
break;
#endif
#ifdef ARCH_openrisc
case bfd_arch_openrisc:
disassemble = print_insn_openrisc;
break;
#endif
#ifdef ARCH_pdp11
case bfd_arch_pdp11:
disassemble = print_insn_pdp11;

533
opcodes/openrisc-asm.c Normal file
View File

@ -0,0 +1,533 @@
/* Assembler interface for targets using CGEN. -*- C -*-
CGEN: Cpu tools GENerator
THIS FILE IS MACHINE GENERATED WITH CGEN.
- the resultant file is machine generated, cgen-asm.in isn't
Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU Binutils and GDB, the GNU debugger.
This program 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.
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
Keep that in mind. */
#include "sysdep.h"
#include <ctype.h>
#include <stdio.h>
#include "ansidecl.h"
#include "bfd.h"
#include "symcat.h"
#include "openrisc-desc.h"
#include "openrisc-opc.h"
#include "opintl.h"
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#undef max
#define max(a,b) ((a) > (b) ? (a) : (b))
static const char * parse_insn_normal
PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *));
/* -- assembler routines inserted here */
/* -- asm.c */
#define CGEN_VERBOSE_ASSEMBLER_ERRORS
long
openrisc_sign_extend_16bit (value)
long value;
{
return (long) (short) value;
}
/* Handle hi(). */
static const char *
parse_hi16 (cd, strp, opindex, valuep)
CGEN_CPU_DESC cd;
const char **strp;
int opindex;
unsigned long *valuep;
{
const char *errmsg;
enum cgen_parse_operand_result result_type;
bfd_vma value;
if (**strp == '#')
++*strp;
if (strncasecmp (*strp, "hi(", 3) == 0)
{
*strp += 3;
#if 0
errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
if (errmsg != NULL)
fprintf (stderr, "parse_hi: %s\n", errmsg);
if (errmsg != NULL)
#endif
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
&result_type, &value);
if (**strp != ')')
return "missing `)'";
++*strp;
if (errmsg == NULL
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
value >>= 16;
*valuep = (long) (short) value;
return errmsg;
}
else
{
if (**strp == '-')
errmsg = cgen_parse_signed_integer (cd, strp, opindex, (long *) &value);
else
errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, &value);
}
*valuep = (long) (short) (value & 0xffff);
return errmsg;
}
/* Handle lo() */
static const char *
parse_lo16 (cd, strp, opindex, valuep)
CGEN_CPU_DESC cd;
const char **strp;
int opindex;
unsigned long *valuep;
{
const char *errmsg;
enum cgen_parse_operand_result result_type;
bfd_vma value;
if (**strp == '#')
++*strp;
if (strncasecmp (*strp, "lo(", 3) == 0)
{
*strp += 3;
#if 0
errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
if (errmsg != NULL)
fprintf (stderr, "parse_lo: %s\n", errmsg);
if (errmsg != NULL)
#endif
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
&result_type, &value);
if (**strp != ')')
return "missing `)'";
++*strp;
if (errmsg == NULL
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
value &= 0xffff;
*valuep = (long) (short) value;
return errmsg;
}
if (**strp == '-')
errmsg = cgen_parse_signed_integer (cd, strp, opindex, (long *) &value);
else
errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, &value);
*valuep = (long) (short) (value & 0xffff);
return errmsg;
}
/* -- */
/* Main entry point for operand parsing.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `parse_insn_normal', but keeping it
separate makes clear the interface between `parse_insn_normal' and each of
the handlers.
*/
const char *
openrisc_cgen_parse_operand (cd, opindex, strp, fields)
CGEN_CPU_DESC cd;
int opindex;
const char ** strp;
CGEN_FIELDS * fields;
{
const char * errmsg = NULL;
/* Used by scalar operands that still need to be parsed. */
long junk;
switch (opindex)
{
case OPENRISC_OPERAND_ABS_26 :
{
bfd_vma value;
errmsg = cgen_parse_address (cd, strp, OPENRISC_OPERAND_ABS_26, 0, NULL, & value);
fields->f_abs26 = value;
}
break;
case OPENRISC_OPERAND_DISP_26 :
{
bfd_vma value;
errmsg = cgen_parse_address (cd, strp, OPENRISC_OPERAND_DISP_26, 0, NULL, & value);
fields->f_disp26 = value;
}
break;
case OPENRISC_OPERAND_HI16 :
errmsg = parse_hi16 (cd, strp, OPENRISC_OPERAND_HI16, &fields->f_simm16);
break;
case OPENRISC_OPERAND_LO16 :
errmsg = parse_lo16 (cd, strp, OPENRISC_OPERAND_LO16, &fields->f_lo16);
break;
case OPENRISC_OPERAND_OP_F_23 :
errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_OP_F_23, &fields->f_op4);
break;
case OPENRISC_OPERAND_OP_F_3 :
errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_OP_F_3, &fields->f_op5);
break;
case OPENRISC_OPERAND_RA :
errmsg = cgen_parse_keyword (cd, strp, & openrisc_cgen_opval_h_gr, & fields->f_r2);
break;
case OPENRISC_OPERAND_RB :
errmsg = cgen_parse_keyword (cd, strp, & openrisc_cgen_opval_h_gr, & fields->f_r3);
break;
case OPENRISC_OPERAND_RD :
errmsg = cgen_parse_keyword (cd, strp, & openrisc_cgen_opval_h_gr, & fields->f_r1);
break;
case OPENRISC_OPERAND_SIMM_16 :
errmsg = cgen_parse_signed_integer (cd, strp, OPENRISC_OPERAND_SIMM_16, &fields->f_simm16);
break;
case OPENRISC_OPERAND_UI16NC :
errmsg = parse_lo16 (cd, strp, OPENRISC_OPERAND_UI16NC, &fields->f_i16nc);
break;
case OPENRISC_OPERAND_UIMM_16 :
errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_UIMM_16, &fields->f_uimm16);
break;
case OPENRISC_OPERAND_UIMM_5 :
errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_UIMM_5, &fields->f_uimm5);
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
abort ();
}
return errmsg;
}
cgen_parse_fn * const openrisc_cgen_parse_handlers[] =
{
parse_insn_normal,
};
void
openrisc_cgen_init_asm (cd)
CGEN_CPU_DESC cd;
{
openrisc_cgen_init_opcode_table (cd);
openrisc_cgen_init_ibld_table (cd);
cd->parse_handlers = & openrisc_cgen_parse_handlers[0];
cd->parse_operand = openrisc_cgen_parse_operand;
}
/* Default insn parser.
The syntax string is scanned and operands are parsed and stored in FIELDS.
Relocs are queued as we go via other callbacks.
??? Note that this is currently an all-or-nothing parser. If we fail to
parse the instruction, we return 0 and the caller will start over from
the beginning. Backtracking will be necessary in parsing subexpressions,
but that can be handled there. Not handling backtracking here may get
expensive in the case of the m68k. Deal with later.
Returns NULL for success, an error message for failure.
*/
static const char *
parse_insn_normal (cd, insn, strp, fields)
CGEN_CPU_DESC cd;
const CGEN_INSN *insn;
const char **strp;
CGEN_FIELDS *fields;
{
/* ??? Runtime added insns not handled yet. */
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
const char *str = *strp;
const char *errmsg;
const char *p;
const CGEN_SYNTAX_CHAR_TYPE * syn;
#ifdef CGEN_MNEMONIC_OPERANDS
/* FIXME: wip */
int past_opcode_p;
#endif
/* For now we assume the mnemonic is first (there are no leading operands).
We can parse it without needing to set up operand parsing.
GAS's input scrubber will ensure mnemonics are lowercase, but we may
not be called from GAS. */
p = CGEN_INSN_MNEMONIC (insn);
while (*p && tolower (*p) == tolower (*str))
++p, ++str;
if (* p)
return _("unrecognized instruction");
#ifndef CGEN_MNEMONIC_OPERANDS
if (* str && !isspace (* str))
return _("unrecognized instruction");
#endif
CGEN_INIT_PARSE (cd);
cgen_init_parse_operand (cd);
#ifdef CGEN_MNEMONIC_OPERANDS
past_opcode_p = 0;
#endif
/* We don't check for (*str != '\0') here because we want to parse
any trailing fake arguments in the syntax string. */
syn = CGEN_SYNTAX_STRING (syntax);
/* Mnemonics come first for now, ensure valid string. */
if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
abort ();
++syn;
while (* syn != 0)
{
/* Non operand chars must match exactly. */
if (CGEN_SYNTAX_CHAR_P (* syn))
{
/* FIXME: While we allow for non-GAS callers above, we assume the
first char after the mnemonic part is a space. */
/* FIXME: We also take inappropriate advantage of the fact that
GAS's input scrubber will remove extraneous blanks. */
if (tolower (*str) == tolower (CGEN_SYNTAX_CHAR (* syn)))
{
#ifdef CGEN_MNEMONIC_OPERANDS
if (CGEN_SYNTAX_CHAR(* syn) == ' ')
past_opcode_p = 1;
#endif
++ syn;
++ str;
}
else if (*str)
{
/* Syntax char didn't match. Can't be this insn. */
static char msg [80];
/* xgettext:c-format */
sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
CGEN_SYNTAX_CHAR(*syn), *str);
return msg;
}
else
{
/* Ran out of input. */
static char msg [80];
/* xgettext:c-format */
sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
CGEN_SYNTAX_CHAR(*syn));
return msg;
}
continue;
}
/* We have an operand of some sort. */
errmsg = openrisc_cgen_parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
&str, fields);
if (errmsg)
return errmsg;
/* Done with this operand, continue with next one. */
++ syn;
}
/* If we're at the end of the syntax string, we're done. */
if (* syn == 0)
{
/* FIXME: For the moment we assume a valid `str' can only contain
blanks now. IE: We needn't try again with a longer version of
the insn and it is assumed that longer versions of insns appear
before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
while (isspace (* str))
++ str;
if (* str != '\0')
return _("junk at end of line"); /* FIXME: would like to include `str' */
return NULL;
}
/* We couldn't parse it. */
return _("unrecognized instruction");
}
/* Main entry point.
This routine is called for each instruction to be assembled.
STR points to the insn to be assembled.
We assume all necessary tables have been initialized.
The assembled instruction, less any fixups, is stored in BUF.
Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
still needs to be converted to target byte order, otherwise BUF is an array
of bytes in target byte order.
The result is a pointer to the insn's entry in the opcode table,
or NULL if an error occured (an error message will have already been
printed).
Note that when processing (non-alias) macro-insns,
this function recurses.
??? It's possible to make this cpu-independent.
One would have to deal with a few minor things.
At this point in time doing so would be more of a curiosity than useful
[for example this file isn't _that_ big], but keeping the possibility in
mind helps keep the design clean. */
const CGEN_INSN *
openrisc_cgen_assemble_insn (cd, str, fields, buf, errmsg)
CGEN_CPU_DESC cd;
const char *str;
CGEN_FIELDS *fields;
CGEN_INSN_BYTES_PTR buf;
char **errmsg;
{
const char *start;
CGEN_INSN_LIST *ilist;
const char *parse_errmsg = NULL;
const char *insert_errmsg = NULL;
/* Skip leading white space. */
while (isspace (* str))
++ str;
/* The instructions are stored in hashed lists.
Get the first in the list. */
ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
/* Keep looking until we find a match. */
start = str;
for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
{
const CGEN_INSN *insn = ilist->insn;
#ifdef CGEN_VALIDATE_INSN_SUPPORTED
/* not usually needed as unsupported opcodes shouldn't be in the hash lists */
/* Is this insn supported by the selected cpu? */
if (! openrisc_cgen_insn_supported (cd, insn))
continue;
#endif
/* If the RELAX attribute is set, this is an insn that shouldn't be
chosen immediately. Instead, it is used during assembler/linker
relaxation if possible. */
if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX) != 0)
continue;
str = start;
/* Allow parse/insert handlers to obtain length of insn. */
CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
if (parse_errmsg != NULL)
continue;
/* ??? 0 is passed for `pc' */
insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
(bfd_vma) 0);
if (insert_errmsg != NULL)
continue;
/* It is up to the caller to actually output the insn and any
queued relocs. */
return insn;
}
{
static char errbuf[150];
#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
const char *tmp_errmsg;
/* If requesting verbose error messages, use insert_errmsg.
Failing that, use parse_errmsg */
tmp_errmsg = (insert_errmsg ? insert_errmsg :
parse_errmsg ? parse_errmsg :
_("unrecognized instruction"));
if (strlen (start) > 50)
/* xgettext:c-format */
sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
else
/* xgettext:c-format */
sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
#else
if (strlen (start) > 50)
/* xgettext:c-format */
sprintf (errbuf, _("bad instruction `%.50s...'"), start);
else
/* xgettext:c-format */
sprintf (errbuf, _("bad instruction `%.50s'"), start);
#endif
*errmsg = errbuf;
return NULL;
}
}
#if 0 /* This calls back to GAS which we can't do without care. */
/* Record each member of OPVALS in the assembler's symbol table.
This lets GAS parse registers for us.
??? Interesting idea but not currently used. */
/* Record each member of OPVALS in the assembler's symbol table.
FIXME: Not currently used. */
void
openrisc_cgen_asm_hash_keywords (cd, opvals)
CGEN_CPU_DESC cd;
CGEN_KEYWORD *opvals;
{
CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
const CGEN_KEYWORD_ENTRY * ke;
while ((ke = cgen_keyword_search_next (& search)) != NULL)
{
#if 0 /* Unnecessary, should be done in the search routine. */
if (! openrisc_cgen_opval_supported (ke))
continue;
#endif
cgen_asm_record_register (cd, ke->name, ke->value);
}
}
#endif /* 0 */

983
opcodes/openrisc-desc.c Normal file
View File

@ -0,0 +1,983 @@
/* CPU data for openrisc.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
This program 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.
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sysdep.h"
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "ansidecl.h"
#include "bfd.h"
#include "symcat.h"
#include "openrisc-desc.h"
#include "openrisc-opc.h"
#include "opintl.h"
#include "libiberty.h"
/* Attributes. */
static const CGEN_ATTR_ENTRY bool_attr[] =
{
{ "#f", 0 },
{ "#t", 1 },
{ 0, 0 }
};
static const CGEN_ATTR_ENTRY MACH_attr[] =
{
{ "base", MACH_BASE },
{ "openrisc", MACH_OPENRISC },
{ "or1300", MACH_OR1300 },
{ "max", MACH_MAX },
{ 0, 0 }
};
static const CGEN_ATTR_ENTRY ISA_attr[] =
{
{ "or32", ISA_OR32 },
{ "max", ISA_MAX },
{ 0, 0 }
};
static const CGEN_ATTR_ENTRY HAS_CACHE_attr[] =
{
{ "DATA_CACHE", HAS_CACHE_DATA_CACHE },
{ "INSN_CACHE", HAS_CACHE_INSN_CACHE },
{ 0, 0 }
};
const CGEN_ATTR_TABLE openrisc_cgen_ifield_attr_table[] =
{
{ "MACH", & MACH_attr[0], & MACH_attr[0] },
{ "VIRTUAL", &bool_attr[0], &bool_attr[0] },
{ "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
{ "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
{ "RESERVED", &bool_attr[0], &bool_attr[0] },
{ "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
{ "SIGNED", &bool_attr[0], &bool_attr[0] },
{ 0, 0, 0 }
};
const CGEN_ATTR_TABLE openrisc_cgen_hardware_attr_table[] =
{
{ "MACH", & MACH_attr[0], & MACH_attr[0] },
{ "VIRTUAL", &bool_attr[0], &bool_attr[0] },
{ "CACHE-ADDR", &bool_attr[0], &bool_attr[0] },
{ "PC", &bool_attr[0], &bool_attr[0] },
{ "PROFILE", &bool_attr[0], &bool_attr[0] },
{ 0, 0, 0 }
};
const CGEN_ATTR_TABLE openrisc_cgen_operand_attr_table[] =
{
{ "MACH", & MACH_attr[0], & MACH_attr[0] },
{ "VIRTUAL", &bool_attr[0], &bool_attr[0] },
{ "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
{ "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
{ "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
{ "SIGNED", &bool_attr[0], &bool_attr[0] },
{ "NEGATIVE", &bool_attr[0], &bool_attr[0] },
{ "RELAX", &bool_attr[0], &bool_attr[0] },
{ "SEM-ONLY", &bool_attr[0], &bool_attr[0] },
{ 0, 0, 0 }
};
const CGEN_ATTR_TABLE openrisc_cgen_insn_attr_table[] =
{
{ "MACH", & MACH_attr[0], & MACH_attr[0] },
{ "ALIAS", &bool_attr[0], &bool_attr[0] },
{ "VIRTUAL", &bool_attr[0], &bool_attr[0] },
{ "UNCOND-CTI", &bool_attr[0], &bool_attr[0] },
{ "COND-CTI", &bool_attr[0], &bool_attr[0] },
{ "SKIP-CTI", &bool_attr[0], &bool_attr[0] },
{ "DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
{ "RELAXABLE", &bool_attr[0], &bool_attr[0] },
{ "RELAX", &bool_attr[0], &bool_attr[0] },
{ "NO-DIS", &bool_attr[0], &bool_attr[0] },
{ "PBB", &bool_attr[0], &bool_attr[0] },
{ "NOT-IN-DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
{ 0, 0, 0 }
};
/* Instruction set variants. */
static const CGEN_ISA openrisc_cgen_isa_table[] = {
{ "or32", 32, 32, 32, 32 },
{ 0, 0, 0, 0, 0 }
};
/* Machine variants. */
static const CGEN_MACH openrisc_cgen_mach_table[] = {
{ "openrisc", "openrisc", MACH_OPENRISC },
{ "or1300", "openrisc:1300", MACH_OR1300 },
{ 0, 0, 0 }
};
static CGEN_KEYWORD_ENTRY openrisc_cgen_opval_h_gr_entries[] =
{
{ "r0", 0, {0, {0}}, 0, 0 },
{ "r1", 1, {0, {0}}, 0, 0 },
{ "r2", 2, {0, {0}}, 0, 0 },
{ "r3", 3, {0, {0}}, 0, 0 },
{ "r4", 4, {0, {0}}, 0, 0 },
{ "r5", 5, {0, {0}}, 0, 0 },
{ "r6", 6, {0, {0}}, 0, 0 },
{ "r7", 7, {0, {0}}, 0, 0 },
{ "r8", 8, {0, {0}}, 0, 0 },
{ "r9", 9, {0, {0}}, 0, 0 },
{ "r10", 10, {0, {0}}, 0, 0 },
{ "r11", 11, {0, {0}}, 0, 0 },
{ "r12", 12, {0, {0}}, 0, 0 },
{ "r13", 13, {0, {0}}, 0, 0 },
{ "r14", 14, {0, {0}}, 0, 0 },
{ "r15", 15, {0, {0}}, 0, 0 },
{ "r16", 16, {0, {0}}, 0, 0 },
{ "r17", 17, {0, {0}}, 0, 0 },
{ "r18", 18, {0, {0}}, 0, 0 },
{ "r19", 19, {0, {0}}, 0, 0 },
{ "r20", 20, {0, {0}}, 0, 0 },
{ "r21", 21, {0, {0}}, 0, 0 },
{ "r22", 22, {0, {0}}, 0, 0 },
{ "r23", 23, {0, {0}}, 0, 0 },
{ "r24", 24, {0, {0}}, 0, 0 },
{ "r25", 25, {0, {0}}, 0, 0 },
{ "r26", 26, {0, {0}}, 0, 0 },
{ "r27", 27, {0, {0}}, 0, 0 },
{ "r28", 28, {0, {0}}, 0, 0 },
{ "r29", 29, {0, {0}}, 0, 0 },
{ "r30", 30, {0, {0}}, 0, 0 },
{ "r31", 31, {0, {0}}, 0, 0 },
{ "lr", 11, {0, {0}}, 0, 0 },
{ "sp", 1, {0, {0}}, 0, 0 },
{ "fp", 2, {0, {0}}, 0, 0 }
};
CGEN_KEYWORD openrisc_cgen_opval_h_gr =
{
& openrisc_cgen_opval_h_gr_entries[0],
35,
0, 0, 0, 0
};
/* The hardware table. */
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define A(a) (1 << CGEN_HW_##a)
#else
#define A(a) (1 << CGEN_HW_/**/a)
#endif
const CGEN_HW_ENTRY openrisc_cgen_hw_table[] =
{
{ "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
{ "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
{ "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
{ "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
{ "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
{ "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PROFILE)|A(PC), { (1<<MACH_BASE) } } },
{ "h-gr", HW_H_GR, CGEN_ASM_KEYWORD, (PTR) & openrisc_cgen_opval_h_gr, { 0|A(PROFILE), { (1<<MACH_BASE) } } },
{ "h-sr", HW_H_SR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
{ "h-hi16", HW_H_HI16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
{ "h-lo16", HW_H_LO16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
{ "h-cbit", HW_H_CBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
{ "h-delay-insn", HW_H_DELAY_INSN, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
{ 0, 0, CGEN_ASM_NONE, 0, {0, {0}} }
};
#undef A
/* The instruction field table. */
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define A(a) (1 << CGEN_IFLD_##a)
#else
#define A(a) (1 << CGEN_IFLD_/**/a)
#endif
const CGEN_IFLD openrisc_cgen_ifld_table[] =
{
{ OPENRISC_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_CLASS, "f-class", 0, 32, 31, 2, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_SUB, "f-sub", 0, 32, 29, 4, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_R1, "f-r1", 0, 32, 25, 5, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_R2, "f-r2", 0, 32, 20, 5, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_R3, "f-r3", 0, 32, 15, 5, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_SIMM16, "f-simm16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_UIMM16, "f-uimm16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_UIMM5, "f-uimm5", 0, 32, 4, 5, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_HI16, "f-hi16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_LO16, "f-lo16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_OP1, "f-op1", 0, 32, 31, 2, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_OP2, "f-op2", 0, 32, 29, 4, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_OP3, "f-op3", 0, 32, 25, 2, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_OP4, "f-op4", 0, 32, 23, 3, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_OP5, "f-op5", 0, 32, 25, 5, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_OP6, "f-op6", 0, 32, 7, 3, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_OP7, "f-op7", 0, 32, 3, 4, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_I16_1, "f-i16-1", 0, 32, 10, 11, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_I16_2, "f-i16-2", 0, 32, 25, 5, { 0, { (1<<MACH_BASE) } } },
{ OPENRISC_F_DISP26, "f-disp26", 0, 32, 25, 26, { 0|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
{ OPENRISC_F_ABS26, "f-abs26", 0, 32, 25, 26, { 0|A(ABS_ADDR), { (1<<MACH_BASE) } } },
{ OPENRISC_F_F_15_8, "f-f-15-8", 0, 32, 15, 8, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
{ OPENRISC_F_F_10_3, "f-f-10-3", 0, 32, 10, 3, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
{ OPENRISC_F_F_4_1, "f-f-4-1", 0, 32, 4, 1, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
{ OPENRISC_F_F_7_3, "f-f-7-3", 0, 32, 7, 3, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
{ OPENRISC_F_F_10_7, "f-f-10-7", 0, 32, 10, 7, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
{ OPENRISC_F_F_10_11, "f-f-10-11", 0, 32, 10, 11, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
{ 0, 0, 0, 0, 0, 0, {0, {0}} }
};
#undef A
/* The operand table. */
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define A(a) (1 << CGEN_OPERAND_##a)
#else
#define A(a) (1 << CGEN_OPERAND_/**/a)
#endif
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define OPERAND(op) OPENRISC_OPERAND_##op
#else
#define OPERAND(op) OPENRISC_OPERAND_/**/op
#endif
const CGEN_OPERAND openrisc_cgen_operand_table[] =
{
/* pc: program counter */
{ "pc", OPENRISC_OPERAND_PC, HW_H_PC, 0, 0,
{ 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
/* sr: special register */
{ "sr", OPENRISC_OPERAND_SR, HW_H_SR, 0, 0,
{ 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
/* cbit: condition bit */
{ "cbit", OPENRISC_OPERAND_CBIT, HW_H_CBIT, 0, 0,
{ 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
/* simm-16: 16 bit signed immediate */
{ "simm-16", OPENRISC_OPERAND_SIMM_16, HW_H_SINT, 15, 16,
{ 0, { (1<<MACH_BASE) } } },
/* uimm-16: 16 bit unsigned immediate */
{ "uimm-16", OPENRISC_OPERAND_UIMM_16, HW_H_UINT, 15, 16,
{ 0, { (1<<MACH_BASE) } } },
/* disp-26: pc-rel 26 bit */
{ "disp-26", OPENRISC_OPERAND_DISP_26, HW_H_IADDR, 25, 26,
{ 0|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
/* abs-26: abs 26 bit */
{ "abs-26", OPENRISC_OPERAND_ABS_26, HW_H_IADDR, 25, 26,
{ 0|A(ABS_ADDR), { (1<<MACH_BASE) } } },
/* uimm-5: imm5 */
{ "uimm-5", OPENRISC_OPERAND_UIMM_5, HW_H_UINT, 4, 5,
{ 0, { (1<<MACH_BASE) } } },
/* rD: destination register */
{ "rD", OPENRISC_OPERAND_RD, HW_H_GR, 25, 5,
{ 0, { (1<<MACH_BASE) } } },
/* rA: source register A */
{ "rA", OPENRISC_OPERAND_RA, HW_H_GR, 20, 5,
{ 0, { (1<<MACH_BASE) } } },
/* rB: source register B */
{ "rB", OPENRISC_OPERAND_RB, HW_H_GR, 15, 5,
{ 0, { (1<<MACH_BASE) } } },
/* op-f-23: f-op23 */
{ "op-f-23", OPENRISC_OPERAND_OP_F_23, HW_H_UINT, 23, 3,
{ 0, { (1<<MACH_BASE) } } },
/* op-f-3: f-op3 */
{ "op-f-3", OPENRISC_OPERAND_OP_F_3, HW_H_UINT, 25, 5,
{ 0, { (1<<MACH_BASE) } } },
/* hi16: high 16 bit immediate, sign optional */
{ "hi16", OPENRISC_OPERAND_HI16, HW_H_HI16, 15, 16,
{ 0|A(SIGN_OPT), { (1<<MACH_BASE) } } },
/* lo16: low 16 bit immediate, sign optional */
{ "lo16", OPENRISC_OPERAND_LO16, HW_H_LO16, 15, 16,
{ 0|A(SIGN_OPT), { (1<<MACH_BASE) } } },
/* ui16nc: 16 bit immediate, sign optional */
{ "ui16nc", OPENRISC_OPERAND_UI16NC, HW_H_LO16, 10, 16,
{ 0|A(SIGN_OPT)|A(VIRTUAL), { (1<<MACH_BASE) } } },
{ 0, 0, 0, 0, 0, {0, {0}} }
};
#undef A
/* The instruction table. */
#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define A(a) (1 << CGEN_INSN_##a)
#else
#define A(a) (1 << CGEN_INSN_/**/a)
#endif
static const CGEN_IBASE openrisc_cgen_insn_table[MAX_INSNS] =
{
/* Special null first entry.
A `num' value of zero is thus invalid.
Also, the special `invalid' insn resides here. */
{ 0, 0, 0, 0, {0, {0}} },
/* l.j ${abs-26} */
{
OPENRISC_INSN_L_J, "l-j", "l.j", 32,
{ 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.jal ${abs-26} */
{
OPENRISC_INSN_L_JAL, "l-jal", "l.jal", 32,
{ 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.jr $rA */
{
OPENRISC_INSN_L_JR, "l-jr", "l.jr", 32,
{ 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.jalr $rA */
{
OPENRISC_INSN_L_JALR, "l-jalr", "l.jalr", 32,
{ 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.bal ${disp-26} */
{
OPENRISC_INSN_L_BAL, "l-bal", "l.bal", 32,
{ 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.bnf ${disp-26} */
{
OPENRISC_INSN_L_BNF, "l-bnf", "l.bnf", 32,
{ 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.bf ${disp-26} */
{
OPENRISC_INSN_L_BF, "l-bf", "l.bf", 32,
{ 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.brk ${uimm-16} */
{
OPENRISC_INSN_L_BRK, "l-brk", "l.brk", 32,
{ 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.rfe $rA */
{
OPENRISC_INSN_L_RFE, "l-rfe", "l.rfe", 32,
{ 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sys ${uimm-16} */
{
OPENRISC_INSN_L_SYS, "l-sys", "l.sys", 32,
{ 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.nop */
{
OPENRISC_INSN_L_NOP, "l-nop", "l.nop", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.movhi $rD,$hi16 */
{
OPENRISC_INSN_L_MOVHI, "l-movhi", "l.movhi", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.mfsr $rD,$rA */
{
OPENRISC_INSN_L_MFSR, "l-mfsr", "l.mfsr", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.mtsr $rA,$rB */
{
OPENRISC_INSN_L_MTSR, "l-mtsr", "l.mtsr", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.lw $rD,${simm-16}($rA) */
{
OPENRISC_INSN_L_LW, "l-lw", "l.lw", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.lbz $rD,${simm-16}($rA) */
{
OPENRISC_INSN_L_LBZ, "l-lbz", "l.lbz", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.lbs $rD,${simm-16}($rA) */
{
OPENRISC_INSN_L_LBS, "l-lbs", "l.lbs", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.lhz $rD,${simm-16}($rA) */
{
OPENRISC_INSN_L_LHZ, "l-lhz", "l.lhz", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.lhs $rD,${simm-16}($rA) */
{
OPENRISC_INSN_L_LHS, "l-lhs", "l.lhs", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sw ${ui16nc}($rA),$rB */
{
OPENRISC_INSN_L_SW, "l-sw", "l.sw", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sb ${ui16nc}($rA),$rB */
{
OPENRISC_INSN_L_SB, "l-sb", "l.sb", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sh ${ui16nc}($rA),$rB */
{
OPENRISC_INSN_L_SH, "l-sh", "l.sh", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sll $rD,$rA,$rB */
{
OPENRISC_INSN_L_SLL, "l-sll", "l.sll", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.slli $rD,$rA,${uimm-5} */
{
OPENRISC_INSN_L_SLLI, "l-slli", "l.slli", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.srl $rD,$rA,$rB */
{
OPENRISC_INSN_L_SRL, "l-srl", "l.srl", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.srli $rD,$rA,${uimm-5} */
{
OPENRISC_INSN_L_SRLI, "l-srli", "l.srli", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.sra $rD,$rA,$rB */
{
OPENRISC_INSN_L_SRA, "l-sra", "l.sra", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.srai $rD,$rA,${uimm-5} */
{
OPENRISC_INSN_L_SRAI, "l-srai", "l.srai", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.ror $rD,$rA,$rB */
{
OPENRISC_INSN_L_ROR, "l-ror", "l.ror", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.rori $rD,$rA,${uimm-5} */
{
OPENRISC_INSN_L_RORI, "l-rori", "l.rori", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.add $rD,$rA,$rB */
{
OPENRISC_INSN_L_ADD, "l-add", "l.add", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.addi $rD,$rA,$lo16 */
{
OPENRISC_INSN_L_ADDI, "l-addi", "l.addi", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.sub $rD,$rA,$rB */
{
OPENRISC_INSN_L_SUB, "l-sub", "l.sub", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.subi $rD,$rA,$lo16 */
{
OPENRISC_INSN_L_SUBI, "l-subi", "l.subi", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.and $rD,$rA,$rB */
{
OPENRISC_INSN_L_AND, "l-and", "l.and", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.andi $rD,$rA,$lo16 */
{
OPENRISC_INSN_L_ANDI, "l-andi", "l.andi", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.or $rD,$rA,$rB */
{
OPENRISC_INSN_L_OR, "l-or", "l.or", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.ori $rD,$rA,$lo16 */
{
OPENRISC_INSN_L_ORI, "l-ori", "l.ori", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.xor $rD,$rA,$rB */
{
OPENRISC_INSN_L_XOR, "l-xor", "l.xor", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.xori $rD,$rA,$lo16 */
{
OPENRISC_INSN_L_XORI, "l-xori", "l.xori", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.mul $rD,$rA,$rB */
{
OPENRISC_INSN_L_MUL, "l-mul", "l.mul", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.muli $rD,$rA,$lo16 */
{
OPENRISC_INSN_L_MULI, "l-muli", "l.muli", 32,
{ 0, { (1<<MACH_BASE) } }
},
/* l.div $rD,$rA,$rB */
{
OPENRISC_INSN_L_DIV, "l-div", "l.div", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.divu $rD,$rA,$rB */
{
OPENRISC_INSN_L_DIVU, "l-divu", "l.divu", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfgts $rA,$rB */
{
OPENRISC_INSN_L_SFGTS, "l-sfgts", "l.sfgts", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfgtu $rA,$rB */
{
OPENRISC_INSN_L_SFGTU, "l-sfgtu", "l.sfgtu", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfges $rA,$rB */
{
OPENRISC_INSN_L_SFGES, "l-sfges", "l.sfges", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfgeu $rA,$rB */
{
OPENRISC_INSN_L_SFGEU, "l-sfgeu", "l.sfgeu", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sflts $rA,$rB */
{
OPENRISC_INSN_L_SFLTS, "l-sflts", "l.sflts", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfltu $rA,$rB */
{
OPENRISC_INSN_L_SFLTU, "l-sfltu", "l.sfltu", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfles $rA,$rB */
{
OPENRISC_INSN_L_SFLES, "l-sfles", "l.sfles", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfleu $rA,$rB */
{
OPENRISC_INSN_L_SFLEU, "l-sfleu", "l.sfleu", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfgtsi $rA,${simm-16} */
{
OPENRISC_INSN_L_SFGTSI, "l-sfgtsi", "l.sfgtsi", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfgtui $rA,${uimm-16} */
{
OPENRISC_INSN_L_SFGTUI, "l-sfgtui", "l.sfgtui", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfgesi $rA,${simm-16} */
{
OPENRISC_INSN_L_SFGESI, "l-sfgesi", "l.sfgesi", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfgeui $rA,${uimm-16} */
{
OPENRISC_INSN_L_SFGEUI, "l-sfgeui", "l.sfgeui", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfltsi $rA,${simm-16} */
{
OPENRISC_INSN_L_SFLTSI, "l-sfltsi", "l.sfltsi", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfltui $rA,${uimm-16} */
{
OPENRISC_INSN_L_SFLTUI, "l-sfltui", "l.sfltui", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sflesi $rA,${simm-16} */
{
OPENRISC_INSN_L_SFLESI, "l-sflesi", "l.sflesi", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfleui $rA,${uimm-16} */
{
OPENRISC_INSN_L_SFLEUI, "l-sfleui", "l.sfleui", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfeq $rA,$rB */
{
OPENRISC_INSN_L_SFEQ, "l-sfeq", "l.sfeq", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfeqi $rA,${simm-16} */
{
OPENRISC_INSN_L_SFEQI, "l-sfeqi", "l.sfeqi", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfne $rA,$rB */
{
OPENRISC_INSN_L_SFNE, "l-sfne", "l.sfne", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
/* l.sfnei $rA,${simm-16} */
{
OPENRISC_INSN_L_SFNEI, "l-sfnei", "l.sfnei", 32,
{ 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
},
};
#undef OP
#undef A
/* Initialize anything needed to be done once, before any cpu_open call. */
static void
init_tables ()
{
}
/* Subroutine of openrisc_cgen_cpu_open to look up a mach via its bfd name. */
static const CGEN_MACH *
lookup_mach_via_bfd_name (table, name)
const CGEN_MACH *table;
const char *name;
{
while (table->name)
{
if (strcmp (name, table->bfd_name) == 0)
return table;
++table;
}
abort ();
}
/* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
static void
build_hw_table (cd)
CGEN_CPU_TABLE *cd;
{
int i;
int machs = cd->machs;
const CGEN_HW_ENTRY *init = & openrisc_cgen_hw_table[0];
/* MAX_HW is only an upper bound on the number of selected entries.
However each entry is indexed by it's enum so there can be holes in
the table. */
const CGEN_HW_ENTRY **selected =
(const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
cd->hw_table.init_entries = init;
cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
/* ??? For now we just use machs to determine which ones we want. */
for (i = 0; init[i].name != NULL; ++i)
if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
& machs)
selected[init[i].type] = &init[i];
cd->hw_table.entries = selected;
cd->hw_table.num_entries = MAX_HW;
}
/* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
static void
build_ifield_table (cd)
CGEN_CPU_TABLE *cd;
{
cd->ifld_table = & openrisc_cgen_ifld_table[0];
}
/* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
static void
build_operand_table (cd)
CGEN_CPU_TABLE *cd;
{
int i;
int machs = cd->machs;
const CGEN_OPERAND *init = & openrisc_cgen_operand_table[0];
/* MAX_OPERANDS is only an upper bound on the number of selected entries.
However each entry is indexed by it's enum so there can be holes in
the table. */
const CGEN_OPERAND **selected =
(const CGEN_OPERAND **) xmalloc (MAX_OPERANDS * sizeof (CGEN_OPERAND *));
cd->operand_table.init_entries = init;
cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
/* ??? For now we just use mach to determine which ones we want. */
for (i = 0; init[i].name != NULL; ++i)
if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
& machs)
selected[init[i].type] = &init[i];
cd->operand_table.entries = selected;
cd->operand_table.num_entries = MAX_OPERANDS;
}
/* Subroutine of openrisc_cgen_cpu_open to build the hardware table.
??? This could leave out insns not supported by the specified mach/isa,
but that would cause errors like "foo only supported by bar" to become
"unknown insn", so for now we include all insns and require the app to
do the checking later.
??? On the other hand, parsing of such insns may require their hardware or
operand elements to be in the table [which they mightn't be]. */
static void
build_insn_table (cd)
CGEN_CPU_TABLE *cd;
{
int i;
const CGEN_IBASE *ib = & openrisc_cgen_insn_table[0];
CGEN_INSN *insns = (CGEN_INSN *) xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
for (i = 0; i < MAX_INSNS; ++i)
insns[i].base = &ib[i];
cd->insn_table.init_entries = insns;
cd->insn_table.entry_size = sizeof (CGEN_IBASE);
cd->insn_table.num_init_entries = MAX_INSNS;
}
/* Subroutine of openrisc_cgen_cpu_open to rebuild the tables. */
static void
openrisc_cgen_rebuild_tables (cd)
CGEN_CPU_TABLE *cd;
{
int i,n_isas;
unsigned int isas = cd->isas;
#if 0
unsigned int machs = cd->machs;
#endif
cd->int_insn_p = CGEN_INT_INSN_P;
/* Data derived from the isa spec. */
#define UNSET (CGEN_SIZE_UNKNOWN + 1)
cd->default_insn_bitsize = UNSET;
cd->base_insn_bitsize = UNSET;
cd->min_insn_bitsize = 65535; /* some ridiculously big number */
cd->max_insn_bitsize = 0;
for (i = 0; i < MAX_ISAS; ++i)
if (((1 << i) & isas) != 0)
{
const CGEN_ISA *isa = & openrisc_cgen_isa_table[i];
/* Default insn sizes of all selected isas must be equal or we set
the result to 0, meaning "unknown". */
if (cd->default_insn_bitsize == UNSET)
cd->default_insn_bitsize = isa->default_insn_bitsize;
else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
; /* this is ok */
else
cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
/* Base insn sizes of all selected isas must be equal or we set
the result to 0, meaning "unknown". */
if (cd->base_insn_bitsize == UNSET)
cd->base_insn_bitsize = isa->base_insn_bitsize;
else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
; /* this is ok */
else
cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
/* Set min,max insn sizes. */
if (isa->min_insn_bitsize < cd->min_insn_bitsize)
cd->min_insn_bitsize = isa->min_insn_bitsize;
if (isa->max_insn_bitsize > cd->max_insn_bitsize)
cd->max_insn_bitsize = isa->max_insn_bitsize;
++n_isas;
}
#if 0 /* Does nothing?? */
/* Data derived from the mach spec. */
for (i = 0; i < MAX_MACHS; ++i)
if (((1 << i) & machs) != 0)
{
const CGEN_MACH *mach = & openrisc_cgen_mach_table[i];
++n_machs;
}
#endif
/* Determine which hw elements are used by MACH. */
build_hw_table (cd);
/* Build the ifield table. */
build_ifield_table (cd);
/* Determine which operands are used by MACH/ISA. */
build_operand_table (cd);
/* Build the instruction table. */
build_insn_table (cd);
}
/* Initialize a cpu table and return a descriptor.
It's much like opening a file, and must be the first function called.
The arguments are a set of (type/value) pairs, terminated with
CGEN_CPU_OPEN_END.
Currently supported values:
CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr
CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr
CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
CGEN_CPU_OPEN_ENDIAN: specify endian choice
CGEN_CPU_OPEN_END: terminates arguments
??? Simultaneous multiple isas might not make sense, but it's not (yet)
precluded.
??? We only support ISO C stdargs here, not K&R.
Laziness, plus experiment to see if anything requires K&R - eventually
K&R will no longer be supported - e.g. GDB is currently trying this. */
CGEN_CPU_DESC
openrisc_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
{
CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
static int init_p;
unsigned int isas = 0; /* 0 = "unspecified" */
unsigned int machs = 0; /* 0 = "unspecified" */
enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
va_list ap;
if (! init_p)
{
init_tables ();
init_p = 1;
}
memset (cd, 0, sizeof (*cd));
va_start (ap, arg_type);
while (arg_type != CGEN_CPU_OPEN_END)
{
switch (arg_type)
{
case CGEN_CPU_OPEN_ISAS :
isas = va_arg (ap, unsigned int);
break;
case CGEN_CPU_OPEN_MACHS :
machs = va_arg (ap, unsigned int);
break;
case CGEN_CPU_OPEN_BFDMACH :
{
const char *name = va_arg (ap, const char *);
const CGEN_MACH *mach =
lookup_mach_via_bfd_name (openrisc_cgen_mach_table, name);
machs |= 1 << mach->num;
break;
}
case CGEN_CPU_OPEN_ENDIAN :
endian = va_arg (ap, enum cgen_endian);
break;
default :
fprintf (stderr, "openrisc_cgen_cpu_open: unsupported argument `%d'\n",
arg_type);
abort (); /* ??? return NULL? */
}
arg_type = va_arg (ap, enum cgen_cpu_open_arg);
}
va_end (ap);
/* mach unspecified means "all" */
if (machs == 0)
machs = (1 << MAX_MACHS) - 1;
/* base mach is always selected */
machs |= 1;
/* isa unspecified means "all" */
if (isas == 0)
isas = (1 << MAX_ISAS) - 1;
if (endian == CGEN_ENDIAN_UNKNOWN)
{
/* ??? If target has only one, could have a default. */
fprintf (stderr, "openrisc_cgen_cpu_open: no endianness specified\n");
abort ();
}
cd->isas = isas;
cd->machs = machs;
cd->endian = endian;
/* FIXME: for the sparc case we can determine insn-endianness statically.
The worry here is where both data and insn endian can be independently
chosen, in which case this function will need another argument.
Actually, will want to allow for more arguments in the future anyway. */
cd->insn_endian = endian;
/* Table (re)builder. */
cd->rebuild_tables = openrisc_cgen_rebuild_tables;
openrisc_cgen_rebuild_tables (cd);
/* Default to not allowing signed overflow. */
cd->signed_overflow_ok_p = 0;
return (CGEN_CPU_DESC) cd;
}
/* Cover fn to openrisc_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
MACH_NAME is the bfd name of the mach. */
CGEN_CPU_DESC
openrisc_cgen_cpu_open_1 (mach_name, endian)
const char *mach_name;
enum cgen_endian endian;
{
return openrisc_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
CGEN_CPU_OPEN_ENDIAN, endian,
CGEN_CPU_OPEN_END);
}
/* Close a cpu table.
??? This can live in a machine independent file, but there's currently
no place to put this file (there's no libcgen). libopcodes is the wrong
place as some simulator ports use this but they don't use libopcodes. */
void
openrisc_cgen_cpu_close (cd)
CGEN_CPU_DESC cd;
{
if (cd->insn_table.init_entries)
free ((CGEN_INSN *) cd->insn_table.init_entries);
if (cd->hw_table.entries)
free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
free (cd);
}

250
opcodes/openrisc-desc.h Normal file
View File

@ -0,0 +1,250 @@
/* CPU data header for openrisc.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
This program 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.
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef OPENRISC_CPU_H
#define OPENRISC_CPU_H
#define CGEN_ARCH openrisc
/* Given symbol S, return openrisc_cgen_<S>. */
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define CGEN_SYM(s) openrisc##_cgen_##s
#else
#define CGEN_SYM(s) openrisc/**/_cgen_/**/s
#endif
/* Selected cpu families. */
#define HAVE_CPU_OPENRISCBF
#define CGEN_INSN_LSB0_P 1
/* Minimum size of any insn (in bytes). */
#define CGEN_MIN_INSN_SIZE 4
/* Maximum size of any insn (in bytes). */
#define CGEN_MAX_INSN_SIZE 4
#define CGEN_INT_INSN_P 1
/* Maximum number of syntax elements in an instruction. */
#define CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS 14
/* CGEN_MNEMONIC_OPERANDS is defined if mnemonics have operands.
e.g. In "b,a foo" the ",a" is an operand. If mnemonics have operands
we can't hash on everything up to the space. */
#define CGEN_MNEMONIC_OPERANDS
/* Maximum number of fields in an instruction. */
#define CGEN_ACTUAL_MAX_IFMT_OPERANDS 9
/* Enums. */
/* Enum declaration for exception vectors. */
typedef enum e_exception {
E_RESET, E_BUSERR, E_DPF, E_IPF
, E_EXTINT, E_ALIGN, E_ILLEGAL, E_PEINT
, E_DTLBMISS, E_ITLBMISS, E_RRANGE, E_SYSCALL
, E_BREAK, E_RESERVED
} E_EXCEPTION;
/* Enum declaration for FIXME. */
typedef enum insn_class {
OP1_0, OP1_1, OP1_2, OP1_3
} INSN_CLASS;
/* Enum declaration for FIXME. */
typedef enum insn_sub {
OP2_0, OP2_1, OP2_2, OP2_3
, OP2_4, OP2_5, OP2_6, OP2_7
, OP2_8, OP2_9, OP2_10, OP2_11
, OP2_12, OP2_13, OP2_14, OP2_15
} INSN_SUB;
/* Enum declaration for FIXME. */
typedef enum insn_op3 {
OP3_0, OP3_1, OP3_2, OP3_3
} INSN_OP3;
/* Enum declaration for FIXME. */
typedef enum insn_op4 {
OP4_0, OP4_1, OP4_2, OP4_3
, OP4_4, OP4_5, OP4_6, OP4_7
} INSN_OP4;
/* Enum declaration for FIXME. */
typedef enum insn_op5 {
OP5_0, OP5_1, OP5_2, OP5_3
, OP5_4, OP5_5, OP5_6, OP5_7
, OP5_8, OP5_9, OP5_10, OP5_11
, OP5_12, OP5_13, OP5_14, OP5_15
, OP5_16, OP5_17, OP5_18, OP5_19
, OP5_20, OP5_21, OP5_22, OP5_23
, OP5_24, OP5_25, OP5_26, OP5_27
, OP5_28, OP5_29, OP5_30, OP5_31
} INSN_OP5;
/* Enum declaration for FIXME. */
typedef enum insn_op6 {
OP6_0, OP6_1, OP6_2, OP6_3
, OP6_4, OP6_5, OP6_6, OP6_7
} INSN_OP6;
/* Enum declaration for FIXME. */
typedef enum insn_op7 {
OP7_0, OP7_1, OP7_2, OP7_3
, OP7_4, OP7_5, OP7_6, OP7_7
, OP7_8, OP7_9, OP7_10, OP7_11
, OP7_12, OP7_13, OP7_14, OP7_15
} INSN_OP7;
/* Attributes. */
/* Enum declaration for machine type selection. */
typedef enum mach_attr {
MACH_BASE, MACH_OPENRISC, MACH_OR1300, MACH_MAX
} MACH_ATTR;
/* Enum declaration for instruction set selection. */
typedef enum isa_attr {
ISA_OR32, ISA_MAX
} ISA_ATTR;
/* Enum declaration for if this model has caches. */
typedef enum has_cache_attr {
HAS_CACHE_DATA_CACHE, HAS_CACHE_INSN_CACHE
} HAS_CACHE_ATTR;
/* Number of architecture variants. */
#define MAX_ISAS 1
#define MAX_MACHS ((int) MACH_MAX)
/* Ifield support. */
extern const struct cgen_ifld openrisc_cgen_ifld_table[];
/* Ifield attribute indices. */
/* Enum declaration for cgen_ifld attrs. */
typedef enum cgen_ifld_attr {
CGEN_IFLD_VIRTUAL, CGEN_IFLD_PCREL_ADDR, CGEN_IFLD_ABS_ADDR, CGEN_IFLD_RESERVED
, CGEN_IFLD_SIGN_OPT, CGEN_IFLD_SIGNED, CGEN_IFLD_END_BOOLS, CGEN_IFLD_START_NBOOLS = 31
, CGEN_IFLD_MACH, CGEN_IFLD_END_NBOOLS
} CGEN_IFLD_ATTR;
/* Number of non-boolean elements in cgen_ifld_attr. */
#define CGEN_IFLD_NBOOL_ATTRS (CGEN_IFLD_END_NBOOLS - CGEN_IFLD_START_NBOOLS - 1)
/* Enum declaration for openrisc ifield types. */
typedef enum ifield_type {
OPENRISC_F_NIL, OPENRISC_F_ANYOF, OPENRISC_F_CLASS, OPENRISC_F_SUB
, OPENRISC_F_R1, OPENRISC_F_R2, OPENRISC_F_R3, OPENRISC_F_SIMM16
, OPENRISC_F_UIMM16, OPENRISC_F_UIMM5, OPENRISC_F_HI16, OPENRISC_F_LO16
, OPENRISC_F_OP1, OPENRISC_F_OP2, OPENRISC_F_OP3, OPENRISC_F_OP4
, OPENRISC_F_OP5, OPENRISC_F_OP6, OPENRISC_F_OP7, OPENRISC_F_I16_1
, OPENRISC_F_I16_2, OPENRISC_F_DISP26, OPENRISC_F_ABS26, OPENRISC_F_I16NC
, OPENRISC_F_F_15_8, OPENRISC_F_F_10_3, OPENRISC_F_F_4_1, OPENRISC_F_F_7_3
, OPENRISC_F_F_10_7, OPENRISC_F_F_10_11, OPENRISC_F_MAX
} IFIELD_TYPE;
#define MAX_IFLD ((int) OPENRISC_F_MAX)
/* Hardware attribute indices. */
/* Enum declaration for cgen_hw attrs. */
typedef enum cgen_hw_attr {
CGEN_HW_VIRTUAL, CGEN_HW_CACHE_ADDR, CGEN_HW_PC, CGEN_HW_PROFILE
, CGEN_HW_END_BOOLS, CGEN_HW_START_NBOOLS = 31, CGEN_HW_MACH, CGEN_HW_END_NBOOLS
} CGEN_HW_ATTR;
/* Number of non-boolean elements in cgen_hw_attr. */
#define CGEN_HW_NBOOL_ATTRS (CGEN_HW_END_NBOOLS - CGEN_HW_START_NBOOLS - 1)
/* Enum declaration for openrisc hardware types. */
typedef enum cgen_hw_type {
HW_H_MEMORY, HW_H_SINT, HW_H_UINT, HW_H_ADDR
, HW_H_IADDR, HW_H_PC, HW_H_GR, HW_H_SR
, HW_H_HI16, HW_H_LO16, HW_H_CBIT, HW_H_DELAY_INSN
, HW_MAX
} CGEN_HW_TYPE;
#define MAX_HW ((int) HW_MAX)
/* Operand attribute indices. */
/* Enum declaration for cgen_operand attrs. */
typedef enum cgen_operand_attr {
CGEN_OPERAND_VIRTUAL, CGEN_OPERAND_PCREL_ADDR, CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_SIGN_OPT
, CGEN_OPERAND_SIGNED, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_RELAX, CGEN_OPERAND_SEM_ONLY
, CGEN_OPERAND_END_BOOLS, CGEN_OPERAND_START_NBOOLS = 31, CGEN_OPERAND_MACH, CGEN_OPERAND_END_NBOOLS
} CGEN_OPERAND_ATTR;
/* Number of non-boolean elements in cgen_operand_attr. */
#define CGEN_OPERAND_NBOOL_ATTRS (CGEN_OPERAND_END_NBOOLS - CGEN_OPERAND_START_NBOOLS - 1)
/* Enum declaration for openrisc operand types. */
typedef enum cgen_operand_type {
OPENRISC_OPERAND_PC, OPENRISC_OPERAND_SR, OPENRISC_OPERAND_CBIT, OPENRISC_OPERAND_SIMM_16
, OPENRISC_OPERAND_UIMM_16, OPENRISC_OPERAND_DISP_26, OPENRISC_OPERAND_ABS_26, OPENRISC_OPERAND_UIMM_5
, OPENRISC_OPERAND_RD, OPENRISC_OPERAND_RA, OPENRISC_OPERAND_RB, OPENRISC_OPERAND_OP_F_23
, OPENRISC_OPERAND_OP_F_3, OPENRISC_OPERAND_HI16, OPENRISC_OPERAND_LO16, OPENRISC_OPERAND_UI16NC
, OPENRISC_OPERAND_MAX
} CGEN_OPERAND_TYPE;
/* Number of operands types. */
#define MAX_OPERANDS 16
/* Maximum number of operands referenced by any insn. */
#define MAX_OPERAND_INSTANCES 8
/* Insn attribute indices. */
/* Enum declaration for cgen_insn attrs. */
typedef enum cgen_insn_attr {
CGEN_INSN_ALIAS, CGEN_INSN_VIRTUAL, CGEN_INSN_UNCOND_CTI, CGEN_INSN_COND_CTI
, CGEN_INSN_SKIP_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_RELAXABLE, CGEN_INSN_RELAX
, CGEN_INSN_NO_DIS, CGEN_INSN_PBB, CGEN_INSN_NOT_IN_DELAY_SLOT, CGEN_INSN_END_BOOLS
, CGEN_INSN_START_NBOOLS = 31, CGEN_INSN_MACH, CGEN_INSN_END_NBOOLS
} CGEN_INSN_ATTR;
/* Number of non-boolean elements in cgen_insn_attr. */
#define CGEN_INSN_NBOOL_ATTRS (CGEN_INSN_END_NBOOLS - CGEN_INSN_START_NBOOLS - 1)
/* cgen.h uses things we just defined. */
#include "opcode/cgen.h"
/* Attributes. */
extern const CGEN_ATTR_TABLE openrisc_cgen_hardware_attr_table[];
extern const CGEN_ATTR_TABLE openrisc_cgen_ifield_attr_table[];
extern const CGEN_ATTR_TABLE openrisc_cgen_operand_attr_table[];
extern const CGEN_ATTR_TABLE openrisc_cgen_insn_attr_table[];
/* Hardware decls. */
extern CGEN_KEYWORD openrisc_cgen_opval_h_gr;
#endif /* OPENRISC_CPU_H */

517
opcodes/openrisc-dis.c Normal file
View File

@ -0,0 +1,517 @@
/* Disassembler interface for targets using CGEN. -*- C -*-
CGEN: Cpu tools GENerator
THIS FILE IS MACHINE GENERATED WITH CGEN.
- the resultant file is machine generated, cgen-dis.in isn't
Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU Binutils and GDB, the GNU debugger.
This program 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.
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
Keep that in mind. */
#include "sysdep.h"
#include <stdio.h>
#include "ansidecl.h"
#include "dis-asm.h"
#include "bfd.h"
#include "symcat.h"
#include "openrisc-desc.h"
#include "openrisc-opc.h"
#include "opintl.h"
/* Default text to print if an instruction isn't recognized. */
#define UNKNOWN_INSN_MSG _("*unknown*")
static void print_normal
PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned int, bfd_vma, int));
static void print_address
PARAMS ((CGEN_CPU_DESC, PTR, bfd_vma, unsigned int, bfd_vma, int));
static void print_keyword
PARAMS ((CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int));
static void print_insn_normal
PARAMS ((CGEN_CPU_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *,
bfd_vma, int));
static int print_insn PARAMS ((CGEN_CPU_DESC, bfd_vma,
disassemble_info *, char *, int));
static int default_print_insn
PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *));
/* -- disassembler routines inserted here */
/* Main entry point for printing operands.
XINFO is a `void *' and not a `disassemble_info *' to not put a requirement
of dis-asm.h on cgen.h.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `print_insn_normal', but keeping it
separate makes clear the interface between `print_insn_normal' and each of
the handlers.
*/
void
openrisc_cgen_print_operand (cd, opindex, xinfo, fields, attrs, pc, length)
CGEN_CPU_DESC cd;
int opindex;
PTR xinfo;
CGEN_FIELDS *fields;
void const *attrs;
bfd_vma pc;
int length;
{
disassemble_info *info = (disassemble_info *) xinfo;
switch (opindex)
{
case OPENRISC_OPERAND_ABS_26 :
print_address (cd, info, fields->f_abs26, 0|(1<<CGEN_OPERAND_ABS_ADDR), pc, length);
break;
case OPENRISC_OPERAND_DISP_26 :
print_address (cd, info, fields->f_disp26, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case OPENRISC_OPERAND_HI16 :
print_normal (cd, info, fields->f_simm16, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_SIGN_OPT), pc, length);
break;
case OPENRISC_OPERAND_LO16 :
print_normal (cd, info, fields->f_lo16, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_SIGN_OPT), pc, length);
break;
case OPENRISC_OPERAND_OP_F_23 :
print_normal (cd, info, fields->f_op4, 0, pc, length);
break;
case OPENRISC_OPERAND_OP_F_3 :
print_normal (cd, info, fields->f_op5, 0, pc, length);
break;
case OPENRISC_OPERAND_RA :
print_keyword (cd, info, & openrisc_cgen_opval_h_gr, fields->f_r2, 0);
break;
case OPENRISC_OPERAND_RB :
print_keyword (cd, info, & openrisc_cgen_opval_h_gr, fields->f_r3, 0);
break;
case OPENRISC_OPERAND_RD :
print_keyword (cd, info, & openrisc_cgen_opval_h_gr, fields->f_r1, 0);
break;
case OPENRISC_OPERAND_SIMM_16 :
print_normal (cd, info, fields->f_simm16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
break;
case OPENRISC_OPERAND_UI16NC :
print_normal (cd, info, fields->f_i16nc, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
break;
case OPENRISC_OPERAND_UIMM_16 :
print_normal (cd, info, fields->f_uimm16, 0, pc, length);
break;
case OPENRISC_OPERAND_UIMM_5 :
print_normal (cd, info, fields->f_uimm5, 0, pc, length);
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
opindex);
abort ();
}
}
cgen_print_fn * const openrisc_cgen_print_handlers[] =
{
print_insn_normal,
};
void
openrisc_cgen_init_dis (cd)
CGEN_CPU_DESC cd;
{
openrisc_cgen_init_opcode_table (cd);
openrisc_cgen_init_ibld_table (cd);
cd->print_handlers = & openrisc_cgen_print_handlers[0];
cd->print_operand = openrisc_cgen_print_operand;
}
/* Default print handler. */
static void
print_normal (cd, dis_info, value, attrs, pc, length)
#ifdef CGEN_PRINT_NORMAL
CGEN_CPU_DESC cd;
#else
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
#endif
PTR dis_info;
long value;
unsigned int attrs;
#ifdef CGEN_PRINT_NORMAL
bfd_vma pc;
int length;
#else
bfd_vma pc ATTRIBUTE_UNUSED;
int length ATTRIBUTE_UNUSED;
#endif
{
disassemble_info *info = (disassemble_info *) dis_info;
#ifdef CGEN_PRINT_NORMAL
CGEN_PRINT_NORMAL (cd, info, value, attrs, pc, length);
#endif
/* Print the operand as directed by the attributes. */
if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
; /* nothing to do */
else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
(*info->fprintf_func) (info->stream, "%ld", value);
else
(*info->fprintf_func) (info->stream, "0x%lx", value);
}
/* Default address handler. */
static void
print_address (cd, dis_info, value, attrs, pc, length)
#ifdef CGEN_PRINT_NORMAL
CGEN_CPU_DESC cd;
#else
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
#endif
PTR dis_info;
bfd_vma value;
unsigned int attrs;
#ifdef CGEN_PRINT_NORMAL
bfd_vma pc;
int length;
#else
bfd_vma pc ATTRIBUTE_UNUSED;
int length ATTRIBUTE_UNUSED;
#endif
{
disassemble_info *info = (disassemble_info *) dis_info;
#ifdef CGEN_PRINT_ADDRESS
CGEN_PRINT_ADDRESS (cd, info, value, attrs, pc, length);
#endif
/* Print the operand as directed by the attributes. */
if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
; /* nothing to do */
else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
(*info->print_address_func) (value, info);
else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
(*info->print_address_func) (value, info);
else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
(*info->fprintf_func) (info->stream, "%ld", (long) value);
else
(*info->fprintf_func) (info->stream, "0x%lx", (long) value);
}
/* Keyword print handler. */
static void
print_keyword (cd, dis_info, keyword_table, value, attrs)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
PTR dis_info;
CGEN_KEYWORD *keyword_table;
long value;
unsigned int attrs ATTRIBUTE_UNUSED;
{
disassemble_info *info = (disassemble_info *) dis_info;
const CGEN_KEYWORD_ENTRY *ke;
ke = cgen_keyword_lookup_value (keyword_table, value);
if (ke != NULL)
(*info->fprintf_func) (info->stream, "%s", ke->name);
else
(*info->fprintf_func) (info->stream, "???");
}
/* Default insn printer.
DIS_INFO is defined as `PTR' so the disassembler needn't know anything
about disassemble_info. */
static void
print_insn_normal (cd, dis_info, insn, fields, pc, length)
CGEN_CPU_DESC cd;
PTR dis_info;
const CGEN_INSN *insn;
CGEN_FIELDS *fields;
bfd_vma pc;
int length;
{
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
disassemble_info *info = (disassemble_info *) dis_info;
const CGEN_SYNTAX_CHAR_TYPE *syn;
CGEN_INIT_PRINT (cd);
for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
{
if (CGEN_SYNTAX_MNEMONIC_P (*syn))
{
(*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
continue;
}
if (CGEN_SYNTAX_CHAR_P (*syn))
{
(*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
continue;
}
/* We have an operand. */
openrisc_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
fields, CGEN_INSN_ATTRS (insn), pc, length);
}
}
/* Subroutine of print_insn. Reads an insn into the given buffers and updates
the extract info.
Returns 0 if all is well, non-zero otherwise. */
static int
read_insn (cd, pc, info, buf, buflen, ex_info, insn_value)
CGEN_CPU_DESC cd;
bfd_vma pc;
disassemble_info *info;
char *buf;
int buflen;
CGEN_EXTRACT_INFO *ex_info;
unsigned long *insn_value;
{
int status = (*info->read_memory_func) (pc, buf, buflen, info);
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return -1;
}
ex_info->dis_info = info;
ex_info->valid = (1 << buflen) - 1;
ex_info->insn_bytes = buf;
*insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
return 0;
}
/* Utility to print an insn.
BUF is the base part of the insn, target byte order, BUFLEN bytes long.
The result is the size of the insn in bytes or zero for an unknown insn
or -1 if an error occurs fetching data (memory_error_func will have
been called). */
static int
print_insn (cd, pc, info, buf, buflen)
CGEN_CPU_DESC cd;
bfd_vma pc;
disassemble_info *info;
char *buf;
int buflen;
{
unsigned long insn_value;
const CGEN_INSN_LIST *insn_list;
CGEN_EXTRACT_INFO ex_info;
int rc = read_insn (cd, pc, info, buf, buflen, & ex_info, & insn_value);
if (rc != 0)
return rc;
/* The instructions are stored in hash lists.
Pick the first one and keep trying until we find the right one. */
insn_list = CGEN_DIS_LOOKUP_INSN (cd, buf, insn_value);
while (insn_list != NULL)
{
const CGEN_INSN *insn = insn_list->insn;
CGEN_FIELDS fields;
int length;
#ifdef CGEN_VALIDATE_INSN_SUPPORTED
/* not needed as insn shouldn't be in hash lists if not supported */
/* Supported by this cpu? */
if (! openrisc_cgen_insn_supported (cd, insn))
{
insn_list = CGEN_DIS_NEXT_INSN (insn_list);
continue;
}
#endif
/* Basic bit mask must be correct. */
/* ??? May wish to allow target to defer this check until the extract
handler. */
if ((insn_value & CGEN_INSN_BASE_MASK (insn))
== CGEN_INSN_BASE_VALUE (insn))
{
/* Printing is handled in two passes. The first pass parses the
machine insn and extracts the fields. The second pass prints
them. */
/* Make sure the entire insn is loaded into insn_value, if it
can fit. */
if (CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize &&
(CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
{
unsigned long full_insn_value;
int rc = read_insn (cd, pc, info, buf,
CGEN_INSN_BITSIZE (insn) / 8,
& ex_info, & full_insn_value);
if (rc != 0)
return rc;
length = CGEN_EXTRACT_FN (cd, insn)
(cd, insn, &ex_info, full_insn_value, &fields, pc);
}
else
length = CGEN_EXTRACT_FN (cd, insn)
(cd, insn, &ex_info, insn_value, &fields, pc);
/* length < 0 -> error */
if (length < 0)
return length;
if (length > 0)
{
CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
/* length is in bits, result is in bytes */
return length / 8;
}
}
insn_list = CGEN_DIS_NEXT_INSN (insn_list);
}
return 0;
}
/* Default value for CGEN_PRINT_INSN.
The result is the size of the insn in bytes or zero for an unknown insn
or -1 if an error occured fetching bytes. */
#ifndef CGEN_PRINT_INSN
#define CGEN_PRINT_INSN default_print_insn
#endif
static int
default_print_insn (cd, pc, info)
CGEN_CPU_DESC cd;
bfd_vma pc;
disassemble_info *info;
{
char buf[CGEN_MAX_INSN_SIZE];
int status;
/* Read the base part of the insn. */
status = (*info->read_memory_func) (pc, buf, cd->base_insn_bitsize / 8, info);
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return -1;
}
return print_insn (cd, pc, info, buf, cd->base_insn_bitsize / 8);
}
/* Main entry point.
Print one instruction from PC on INFO->STREAM.
Return the size of the instruction (in bytes). */
int
print_insn_openrisc (pc, info)
bfd_vma pc;
disassemble_info *info;
{
static CGEN_CPU_DESC cd = 0;
static int prev_isa;
static int prev_mach;
static int prev_endian;
int length;
int isa,mach;
int endian = (info->endian == BFD_ENDIAN_BIG
? CGEN_ENDIAN_BIG
: CGEN_ENDIAN_LITTLE);
enum bfd_architecture arch;
/* ??? gdb will set mach but leave the architecture as "unknown" */
#ifndef CGEN_BFD_ARCH
#define CGEN_BFD_ARCH bfd_arch_openrisc
#endif
arch = info->arch;
if (arch == bfd_arch_unknown)
arch = CGEN_BFD_ARCH;
/* There's no standard way to compute the machine or isa number
so we leave it to the target. */
#ifdef CGEN_COMPUTE_MACH
mach = CGEN_COMPUTE_MACH (info);
#else
mach = info->mach;
#endif
#ifdef CGEN_COMPUTE_ISA
isa = CGEN_COMPUTE_ISA (info);
#else
isa = 0;
#endif
/* If we've switched cpu's, close the current table and open a new one. */
if (cd
&& (isa != prev_isa
|| mach != prev_mach
|| endian != prev_endian))
{
openrisc_cgen_cpu_close (cd);
cd = 0;
}
/* If we haven't initialized yet, initialize the opcode table. */
if (! cd)
{
const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
const char *mach_name;
if (!arch_type)
abort ();
mach_name = arch_type->printable_name;
prev_isa = isa;
prev_mach = mach;
prev_endian = endian;
cd = openrisc_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
CGEN_CPU_OPEN_BFDMACH, mach_name,
CGEN_CPU_OPEN_ENDIAN, prev_endian,
CGEN_CPU_OPEN_END);
if (!cd)
abort ();
openrisc_cgen_init_dis (cd);
}
/* We try to have as much common code as possible.
But at this point some targets need to take over. */
/* ??? Some targets may need a hook elsewhere. Try to avoid this,
but if not possible try to move this hook elsewhere rather than
have two hooks. */
length = CGEN_PRINT_INSN (cd, pc, info);
if (length > 0)
return length;
if (length < 0)
return -1;
(*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
return cd->default_insn_bitsize / 8;
}

982
opcodes/openrisc-ibld.c Normal file
View File

@ -0,0 +1,982 @@
/* Instruction building/extraction support for openrisc. -*- C -*-
THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
- the resultant file is machine generated, cgen-ibld.in isn't
Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU Binutils and GDB, the GNU debugger.
This program 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.
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
Keep that in mind. */
#include "sysdep.h"
#include <ctype.h>
#include <stdio.h>
#include "ansidecl.h"
#include "dis-asm.h"
#include "bfd.h"
#include "symcat.h"
#include "openrisc-desc.h"
#include "openrisc-opc.h"
#include "opintl.h"
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#undef max
#define max(a,b) ((a) > (b) ? (a) : (b))
/* Used by the ifield rtx function. */
#define FLD(f) (fields->f)
static const char * insert_normal
PARAMS ((CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR));
static const char * insert_insn_normal
PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *,
CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
static int extract_normal
PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
unsigned int, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, bfd_vma, long *));
static int extract_insn_normal
PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
static void put_insn_int_value
PARAMS ((CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT));
/* Operand insertion. */
#if ! CGEN_INT_INSN_P
/* Subroutine of insert_normal. */
static CGEN_INLINE void
insert_1 (cd, value, start, length, word_length, bufp)
CGEN_CPU_DESC cd;
unsigned long value;
int start,length,word_length;
unsigned char *bufp;
{
unsigned long x,mask;
int shift;
int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
x = bfd_get_bits (bufp, word_length, big_p);
/* Written this way to avoid undefined behaviour. */
mask = (((1L << (length - 1)) - 1) << 1) | 1;
if (CGEN_INSN_LSB0_P)
shift = (start + 1) - length;
else
shift = (word_length - (start + length));
x = (x & ~(mask << shift)) | ((value & mask) << shift);
bfd_put_bits ((bfd_vma) x, bufp, word_length, big_p);
}
#endif /* ! CGEN_INT_INSN_P */
/* Default insertion routine.
ATTRS is a mask of the boolean attributes.
WORD_OFFSET is the offset in bits from the start of the insn of the value.
WORD_LENGTH is the length of the word in bits in which the value resides.
START is the starting bit number in the word, architecture origin.
LENGTH is the length of VALUE in bits.
TOTAL_LENGTH is the total length of the insn in bits.
The result is an error message or NULL if success. */
/* ??? This duplicates functionality with bfd's howto table and
bfd_install_relocation. */
/* ??? This doesn't handle bfd_vma's. Create another function when
necessary. */
static const char *
insert_normal (cd, value, attrs, word_offset, start, length, word_length,
total_length, buffer)
CGEN_CPU_DESC cd;
long value;
unsigned int attrs;
unsigned int word_offset, start, length, word_length, total_length;
CGEN_INSN_BYTES_PTR buffer;
{
static char errbuf[100];
/* Written this way to avoid undefined behaviour. */
unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
/* If LENGTH is zero, this operand doesn't contribute to the value. */
if (length == 0)
return NULL;
#if 0
if (CGEN_INT_INSN_P
&& word_offset != 0)
abort ();
#endif
if (word_length > 32)
abort ();
/* For architectures with insns smaller than the base-insn-bitsize,
word_length may be too big. */
if (cd->min_insn_bitsize < cd->base_insn_bitsize)
{
if (word_offset == 0
&& word_length > total_length)
word_length = total_length;
}
/* Ensure VALUE will fit. */
if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
{
unsigned long maxval = mask;
if ((unsigned long) value > maxval)
{
/* xgettext:c-format */
sprintf (errbuf,
_("operand out of range (%lu not between 0 and %lu)"),
value, maxval);
return errbuf;
}
}
else
{
if (! cgen_signed_overflow_ok_p (cd))
{
long minval = - (1L << (length - 1));
long maxval = (1L << (length - 1)) - 1;
if (value < minval || value > maxval)
{
sprintf
/* xgettext:c-format */
(errbuf, _("operand out of range (%ld not between %ld and %ld)"),
value, minval, maxval);
return errbuf;
}
}
}
#if CGEN_INT_INSN_P
{
int shift;
if (CGEN_INSN_LSB0_P)
shift = (word_offset + start + 1) - length;
else
shift = total_length - (word_offset + start + length);
*buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
}
#else /* ! CGEN_INT_INSN_P */
{
unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
insert_1 (cd, value, start, length, word_length, bufp);
}
#endif /* ! CGEN_INT_INSN_P */
return NULL;
}
/* Default insn builder (insert handler).
The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
recorded in host byte order, otherwise BUFFER is an array of bytes
and the value is recorded in target byte order).
The result is an error message or NULL if success. */
static const char *
insert_insn_normal (cd, insn, fields, buffer, pc)
CGEN_CPU_DESC cd;
const CGEN_INSN * insn;
CGEN_FIELDS * fields;
CGEN_INSN_BYTES_PTR buffer;
bfd_vma pc;
{
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
unsigned long value;
const CGEN_SYNTAX_CHAR_TYPE * syn;
CGEN_INIT_INSERT (cd);
value = CGEN_INSN_BASE_VALUE (insn);
/* If we're recording insns as numbers (rather than a string of bytes),
target byte order handling is deferred until later. */
#if CGEN_INT_INSN_P
put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
CGEN_FIELDS_BITSIZE (fields), value);
#else
cgen_put_insn_value (cd, buffer, min (cd->base_insn_bitsize,
CGEN_FIELDS_BITSIZE (fields)),
value);
#endif /* ! CGEN_INT_INSN_P */
/* ??? It would be better to scan the format's fields.
Still need to be able to insert a value based on the operand though;
e.g. storing a branch displacement that got resolved later.
Needs more thought first. */
for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
{
const char *errmsg;
if (CGEN_SYNTAX_CHAR_P (* syn))
continue;
errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
fields, buffer, pc);
if (errmsg)
return errmsg;
}
return NULL;
}
/* Cover function to store an insn value into an integral insn. Must go here
because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
static void
put_insn_int_value (cd, buf, length, insn_length, value)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
CGEN_INSN_BYTES_PTR buf;
int length;
int insn_length;
CGEN_INSN_INT value;
{
/* For architectures with insns smaller than the base-insn-bitsize,
length may be too big. */
if (length > insn_length)
*buf = value;
else
{
int shift = insn_length - length;
/* Written this way to avoid undefined behaviour. */
CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
*buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
}
}
/* Operand extraction. */
#if ! CGEN_INT_INSN_P
/* Subroutine of extract_normal.
Ensure sufficient bytes are cached in EX_INFO.
OFFSET is the offset in bytes from the start of the insn of the value.
BYTES is the length of the needed value.
Returns 1 for success, 0 for failure. */
static CGEN_INLINE int
fill_cache (cd, ex_info, offset, bytes, pc)
CGEN_CPU_DESC cd;
CGEN_EXTRACT_INFO *ex_info;
int offset, bytes;
bfd_vma pc;
{
/* It's doubtful that the middle part has already been fetched so
we don't optimize that case. kiss. */
int mask;
disassemble_info *info = (disassemble_info *) ex_info->dis_info;
/* First do a quick check. */
mask = (1 << bytes) - 1;
if (((ex_info->valid >> offset) & mask) == mask)
return 1;
/* Search for the first byte we need to read. */
for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
if (! (mask & ex_info->valid))
break;
if (bytes)
{
int status;
pc += offset;
status = (*info->read_memory_func)
(pc, ex_info->insn_bytes + offset, bytes, info);
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return 0;
}
ex_info->valid |= ((1 << bytes) - 1) << offset;
}
return 1;
}
/* Subroutine of extract_normal. */
static CGEN_INLINE long
extract_1 (cd, ex_info, start, length, word_length, bufp, pc)
CGEN_CPU_DESC cd;
CGEN_EXTRACT_INFO *ex_info;
int start,length,word_length;
unsigned char *bufp;
bfd_vma pc;
{
unsigned long x;
int shift;
int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
x = bfd_get_bits (bufp, word_length, big_p);
if (CGEN_INSN_LSB0_P)
shift = (start + 1) - length;
else
shift = (word_length - (start + length));
return x >> shift;
}
#endif /* ! CGEN_INT_INSN_P */
/* Default extraction routine.
INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
or sometimes less for cases like the m32r where the base insn size is 32
but some insns are 16 bits.
ATTRS is a mask of the boolean attributes. We only need `SIGNED',
but for generality we take a bitmask of all of them.
WORD_OFFSET is the offset in bits from the start of the insn of the value.
WORD_LENGTH is the length of the word in bits in which the value resides.
START is the starting bit number in the word, architecture origin.
LENGTH is the length of VALUE in bits.
TOTAL_LENGTH is the total length of the insn in bits.
Returns 1 for success, 0 for failure. */
/* ??? The return code isn't properly used. wip. */
/* ??? This doesn't handle bfd_vma's. Create another function when
necessary. */
static int
extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
word_length, total_length, pc, valuep)
CGEN_CPU_DESC cd;
#if ! CGEN_INT_INSN_P
CGEN_EXTRACT_INFO *ex_info;
#else
CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED;
#endif
CGEN_INSN_INT insn_value;
unsigned int attrs;
unsigned int word_offset, start, length, word_length, total_length;
#if ! CGEN_INT_INSN_P
bfd_vma pc;
#else
bfd_vma pc ATTRIBUTE_UNUSED;
#endif
long *valuep;
{
CGEN_INSN_INT value, mask;
/* If LENGTH is zero, this operand doesn't contribute to the value
so give it a standard value of zero. */
if (length == 0)
{
*valuep = 0;
return 1;
}
#if 0
if (CGEN_INT_INSN_P
&& word_offset != 0)
abort ();
#endif
if (word_length > 32)
abort ();
/* For architectures with insns smaller than the insn-base-bitsize,
word_length may be too big. */
if (cd->min_insn_bitsize < cd->base_insn_bitsize)
{
if (word_offset == 0
&& word_length > total_length)
word_length = total_length;
}
/* Does the value reside in INSN_VALUE? */
if (CGEN_INT_INSN_P || word_offset == 0)
{
if (CGEN_INSN_LSB0_P)
value = insn_value >> ((word_offset + start + 1) - length);
else
value = insn_value >> (total_length - ( word_offset + start + length));
}
#if ! CGEN_INT_INSN_P
else
{
unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
if (word_length > 32)
abort ();
if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
return 0;
value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
}
#endif /* ! CGEN_INT_INSN_P */
/* Written this way to avoid undefined behaviour. */
mask = (((1L << (length - 1)) - 1) << 1) | 1;
value &= mask;
/* sign extend? */
if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
&& (value & (1L << (length - 1))))
value |= ~mask;
*valuep = value;
return 1;
}
/* Default insn extractor.
INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
The extracted fields are stored in FIELDS.
EX_INFO is used to handle reading variable length insns.
Return the length of the insn in bits, or 0 if no match,
or -1 if an error occurs fetching data (memory_error_func will have
been called). */
static int
extract_insn_normal (cd, insn, ex_info, insn_value, fields, pc)
CGEN_CPU_DESC cd;
const CGEN_INSN *insn;
CGEN_EXTRACT_INFO *ex_info;
CGEN_INSN_INT insn_value;
CGEN_FIELDS *fields;
bfd_vma pc;
{
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
const CGEN_SYNTAX_CHAR_TYPE *syn;
CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
CGEN_INIT_EXTRACT (cd);
for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
{
int length;
if (CGEN_SYNTAX_CHAR_P (*syn))
continue;
length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
ex_info, insn_value, fields, pc);
if (length <= 0)
return length;
}
/* We recognized and successfully extracted this insn. */
return CGEN_INSN_BITSIZE (insn);
}
/* machine generated code added here */
/* Main entry point for operand insertion.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `parse_insn_normal', but keeping it
separate makes clear the interface between `parse_insn_normal' and each of
the handlers. It's also needed by GAS to insert operands that couldn't be
resolved during parsing.
*/
const char *
openrisc_cgen_insert_operand (cd, opindex, fields, buffer, pc)
CGEN_CPU_DESC cd;
int opindex;
CGEN_FIELDS * fields;
CGEN_INSN_BYTES_PTR buffer;
bfd_vma pc;
{
const char * errmsg = NULL;
unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
switch (opindex)
{
case OPENRISC_OPERAND_ABS_26 :
{
long value = fields->f_abs26;
value = ((unsigned int) (pc) >> (2));
errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_ABS_ADDR), 0, 25, 26, 32, total_length, buffer);
}
break;
case OPENRISC_OPERAND_DISP_26 :
{
long value = fields->f_disp26;
value = ((int) (((value) - (pc))) >> (2));
errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 25, 26, 32, total_length, buffer);
}
break;
case OPENRISC_OPERAND_HI16 :
errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
break;
case OPENRISC_OPERAND_LO16 :
errmsg = insert_normal (cd, fields->f_lo16, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
break;
case OPENRISC_OPERAND_OP_F_23 :
errmsg = insert_normal (cd, fields->f_op4, 0, 0, 23, 3, 32, total_length, buffer);
break;
case OPENRISC_OPERAND_OP_F_3 :
errmsg = insert_normal (cd, fields->f_op5, 0, 0, 25, 5, 32, total_length, buffer);
break;
case OPENRISC_OPERAND_RA :
errmsg = insert_normal (cd, fields->f_r2, 0, 0, 20, 5, 32, total_length, buffer);
break;
case OPENRISC_OPERAND_RB :
errmsg = insert_normal (cd, fields->f_r3, 0, 0, 15, 5, 32, total_length, buffer);
break;
case OPENRISC_OPERAND_RD :
errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer);
break;
case OPENRISC_OPERAND_SIMM_16 :
errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
break;
case OPENRISC_OPERAND_UI16NC :
{
{
FLD (f_i16_2) = ((((unsigned int) (FLD (f_i16nc)) >> (11))) & (31));
FLD (f_i16_1) = ((FLD (f_i16nc)) & (2047));
}
errmsg = insert_normal (cd, fields->f_i16_1, 0, 0, 10, 11, 32, total_length, buffer);
if (errmsg)
break;
errmsg = insert_normal (cd, fields->f_i16_2, 0, 0, 25, 5, 32, total_length, buffer);
if (errmsg)
break;
}
break;
case OPENRISC_OPERAND_UIMM_16 :
errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 15, 16, 32, total_length, buffer);
break;
case OPENRISC_OPERAND_UIMM_5 :
errmsg = insert_normal (cd, fields->f_uimm5, 0, 0, 4, 5, 32, total_length, buffer);
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
opindex);
abort ();
}
return errmsg;
}
/* Main entry point for operand extraction.
The result is <= 0 for error, >0 for success.
??? Actual values aren't well defined right now.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `print_insn_normal', but keeping it
separate makes clear the interface between `print_insn_normal' and each of
the handlers.
*/
int
openrisc_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
CGEN_CPU_DESC cd;
int opindex;
CGEN_EXTRACT_INFO *ex_info;
CGEN_INSN_INT insn_value;
CGEN_FIELDS * fields;
bfd_vma pc;
{
/* Assume success (for those operands that are nops). */
int length = 1;
unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
switch (opindex)
{
case OPENRISC_OPERAND_ABS_26 :
{
long value;
length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_ABS_ADDR), 0, 25, 26, 32, total_length, pc, & value);
value = ((value) << (2));
fields->f_abs26 = value;
}
break;
case OPENRISC_OPERAND_DISP_26 :
{
long value;
length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 25, 26, 32, total_length, pc, & value);
value = ((((value) << (2))) + (pc));
fields->f_disp26 = value;
}
break;
case OPENRISC_OPERAND_HI16 :
length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & fields->f_simm16);
break;
case OPENRISC_OPERAND_LO16 :
length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & fields->f_lo16);
break;
case OPENRISC_OPERAND_OP_F_23 :
length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 3, 32, total_length, pc, & fields->f_op4);
break;
case OPENRISC_OPERAND_OP_F_3 :
length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_op5);
break;
case OPENRISC_OPERAND_RA :
length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_r2);
break;
case OPENRISC_OPERAND_RB :
length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_r3);
break;
case OPENRISC_OPERAND_RD :
length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1);
break;
case OPENRISC_OPERAND_SIMM_16 :
length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & fields->f_simm16);
break;
case OPENRISC_OPERAND_UI16NC :
{
length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 11, 32, total_length, pc, & fields->f_i16_1);
if (length <= 0) break;
length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_i16_2);
if (length <= 0) break;
{
FLD (f_i16nc) = openrisc_sign_extend_16bit (((((FLD (f_i16_2)) << (11))) | (FLD (f_i16_1))));
}
}
break;
case OPENRISC_OPERAND_UIMM_16 :
length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_uimm16);
break;
case OPENRISC_OPERAND_UIMM_5 :
length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 5, 32, total_length, pc, & fields->f_uimm5);
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
opindex);
abort ();
}
return length;
}
cgen_insert_fn * const openrisc_cgen_insert_handlers[] =
{
insert_insn_normal,
};
cgen_extract_fn * const openrisc_cgen_extract_handlers[] =
{
extract_insn_normal,
};
/* Getting values from cgen_fields is handled by a collection of functions.
They are distinguished by the type of the VALUE argument they return.
TODO: floating point, inlining support, remove cases where result type
not appropriate. */
int
openrisc_cgen_get_int_operand (cd, opindex, fields)
CGEN_CPU_DESC cd;
int opindex;
const CGEN_FIELDS * fields;
{
int value;
switch (opindex)
{
case OPENRISC_OPERAND_ABS_26 :
value = fields->f_abs26;
break;
case OPENRISC_OPERAND_DISP_26 :
value = fields->f_disp26;
break;
case OPENRISC_OPERAND_HI16 :
value = fields->f_simm16;
break;
case OPENRISC_OPERAND_LO16 :
value = fields->f_lo16;
break;
case OPENRISC_OPERAND_OP_F_23 :
value = fields->f_op4;
break;
case OPENRISC_OPERAND_OP_F_3 :
value = fields->f_op5;
break;
case OPENRISC_OPERAND_RA :
value = fields->f_r2;
break;
case OPENRISC_OPERAND_RB :
value = fields->f_r3;
break;
case OPENRISC_OPERAND_RD :
value = fields->f_r1;
break;
case OPENRISC_OPERAND_SIMM_16 :
value = fields->f_simm16;
break;
case OPENRISC_OPERAND_UI16NC :
value = fields->f_i16nc;
break;
case OPENRISC_OPERAND_UIMM_16 :
value = fields->f_uimm16;
break;
case OPENRISC_OPERAND_UIMM_5 :
value = fields->f_uimm5;
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
opindex);
abort ();
}
return value;
}
bfd_vma
openrisc_cgen_get_vma_operand (cd, opindex, fields)
CGEN_CPU_DESC cd;
int opindex;
const CGEN_FIELDS * fields;
{
bfd_vma value;
switch (opindex)
{
case OPENRISC_OPERAND_ABS_26 :
value = fields->f_abs26;
break;
case OPENRISC_OPERAND_DISP_26 :
value = fields->f_disp26;
break;
case OPENRISC_OPERAND_HI16 :
value = fields->f_simm16;
break;
case OPENRISC_OPERAND_LO16 :
value = fields->f_lo16;
break;
case OPENRISC_OPERAND_OP_F_23 :
value = fields->f_op4;
break;
case OPENRISC_OPERAND_OP_F_3 :
value = fields->f_op5;
break;
case OPENRISC_OPERAND_RA :
value = fields->f_r2;
break;
case OPENRISC_OPERAND_RB :
value = fields->f_r3;
break;
case OPENRISC_OPERAND_RD :
value = fields->f_r1;
break;
case OPENRISC_OPERAND_SIMM_16 :
value = fields->f_simm16;
break;
case OPENRISC_OPERAND_UI16NC :
value = fields->f_i16nc;
break;
case OPENRISC_OPERAND_UIMM_16 :
value = fields->f_uimm16;
break;
case OPENRISC_OPERAND_UIMM_5 :
value = fields->f_uimm5;
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
opindex);
abort ();
}
return value;
}
/* Stuffing values in cgen_fields is handled by a collection of functions.
They are distinguished by the type of the VALUE argument they accept.
TODO: floating point, inlining support, remove cases where argument type
not appropriate. */
void
openrisc_cgen_set_int_operand (cd, opindex, fields, value)
CGEN_CPU_DESC cd;
int opindex;
CGEN_FIELDS * fields;
int value;
{
switch (opindex)
{
case OPENRISC_OPERAND_ABS_26 :
fields->f_abs26 = value;
break;
case OPENRISC_OPERAND_DISP_26 :
fields->f_disp26 = value;
break;
case OPENRISC_OPERAND_HI16 :
fields->f_simm16 = value;
break;
case OPENRISC_OPERAND_LO16 :
fields->f_lo16 = value;
break;
case OPENRISC_OPERAND_OP_F_23 :
fields->f_op4 = value;
break;
case OPENRISC_OPERAND_OP_F_3 :
fields->f_op5 = value;
break;
case OPENRISC_OPERAND_RA :
fields->f_r2 = value;
break;
case OPENRISC_OPERAND_RB :
fields->f_r3 = value;
break;
case OPENRISC_OPERAND_RD :
fields->f_r1 = value;
break;
case OPENRISC_OPERAND_SIMM_16 :
fields->f_simm16 = value;
break;
case OPENRISC_OPERAND_UI16NC :
fields->f_i16nc = value;
break;
case OPENRISC_OPERAND_UIMM_16 :
fields->f_uimm16 = value;
break;
case OPENRISC_OPERAND_UIMM_5 :
fields->f_uimm5 = value;
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
opindex);
abort ();
}
}
void
openrisc_cgen_set_vma_operand (cd, opindex, fields, value)
CGEN_CPU_DESC cd;
int opindex;
CGEN_FIELDS * fields;
bfd_vma value;
{
switch (opindex)
{
case OPENRISC_OPERAND_ABS_26 :
fields->f_abs26 = value;
break;
case OPENRISC_OPERAND_DISP_26 :
fields->f_disp26 = value;
break;
case OPENRISC_OPERAND_HI16 :
fields->f_simm16 = value;
break;
case OPENRISC_OPERAND_LO16 :
fields->f_lo16 = value;
break;
case OPENRISC_OPERAND_OP_F_23 :
fields->f_op4 = value;
break;
case OPENRISC_OPERAND_OP_F_3 :
fields->f_op5 = value;
break;
case OPENRISC_OPERAND_RA :
fields->f_r2 = value;
break;
case OPENRISC_OPERAND_RB :
fields->f_r3 = value;
break;
case OPENRISC_OPERAND_RD :
fields->f_r1 = value;
break;
case OPENRISC_OPERAND_SIMM_16 :
fields->f_simm16 = value;
break;
case OPENRISC_OPERAND_UI16NC :
fields->f_i16nc = value;
break;
case OPENRISC_OPERAND_UIMM_16 :
fields->f_uimm16 = value;
break;
case OPENRISC_OPERAND_UIMM_5 :
fields->f_uimm5 = value;
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
opindex);
abort ();
}
}
/* Function to call before using the instruction builder tables. */
void
openrisc_cgen_init_ibld_table (cd)
CGEN_CPU_DESC cd;
{
cd->insert_handlers = & openrisc_cgen_insert_handlers[0];
cd->extract_handlers = & openrisc_cgen_extract_handlers[0];
cd->insert_operand = openrisc_cgen_insert_operand;
cd->extract_operand = openrisc_cgen_extract_operand;
cd->get_int_operand = openrisc_cgen_get_int_operand;
cd->set_int_operand = openrisc_cgen_set_int_operand;
cd->get_vma_operand = openrisc_cgen_get_vma_operand;
cd->set_vma_operand = openrisc_cgen_set_vma_operand;
}

701
opcodes/openrisc-opc.c Normal file
View File

@ -0,0 +1,701 @@
/* Instruction opcode table for openrisc.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
This program 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.
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sysdep.h"
#include "ansidecl.h"
#include "bfd.h"
#include "symcat.h"
#include "openrisc-desc.h"
#include "openrisc-opc.h"
#include "libiberty.h"
/* -- opc.c */
/* -- */
/* The hash functions are recorded here to help keep assembler code out of
the disassembler and vice versa. */
static int asm_hash_insn_p PARAMS ((const CGEN_INSN *));
static unsigned int asm_hash_insn PARAMS ((const char *));
static int dis_hash_insn_p PARAMS ((const CGEN_INSN *));
static unsigned int dis_hash_insn PARAMS ((const char *, CGEN_INSN_INT));
/* Instruction formats. */
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define F(f) & openrisc_cgen_ifld_table[OPENRISC_##f]
#else
#define F(f) & openrisc_cgen_ifld_table[OPENRISC_/**/f]
#endif
static const CGEN_IFMT ifmt_empty = {
0, 0, 0x0, { { 0 } }
};
static const CGEN_IFMT ifmt_l_j = {
32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_ABS26) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_jr = {
32, 32, 0xffe00000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_OP3) }, { F (F_OP4) }, { F (F_R2) }, { F (F_UIMM16) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_bal = {
32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_DISP26) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_movhi = {
32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_SIMM16) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_mfsr = {
32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_UIMM16) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_mtsr = {
32, 32, 0xfc0007ff, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_R3) }, { F (F_I16_1) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_lw = {
32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_SIMM16) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_sw = {
32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R3) }, { F (F_I16NC) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_sll = {
32, 32, 0xfc0007ff, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_R3) }, { F (F_F_10_3) }, { F (F_OP6) }, { F (F_F_4_1) }, { F (F_OP7) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_slli = {
32, 32, 0xfc00ffe0, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_F_15_8) }, { F (F_OP6) }, { F (F_UIMM5) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_add = {
32, 32, 0xfc0007ff, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_R3) }, { F (F_F_10_7) }, { F (F_OP7) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_addi = {
32, 32, 0xfc000000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_R1) }, { F (F_R2) }, { F (F_LO16) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_sfgts = {
32, 32, 0xffe007ff, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_OP5) }, { F (F_R2) }, { F (F_R3) }, { F (F_F_10_11) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_sfgtsi = {
32, 32, 0xffe00000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_OP5) }, { F (F_R2) }, { F (F_SIMM16) }, { 0 } }
};
static const CGEN_IFMT ifmt_l_sfgtui = {
32, 32, 0xffe00000, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_OP5) }, { F (F_R2) }, { F (F_UIMM16) }, { 0 } }
};
#undef F
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define A(a) (1 << CGEN_INSN_##a)
#else
#define A(a) (1 << CGEN_INSN_/**/a)
#endif
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define OPERAND(op) OPENRISC_OPERAND_##op
#else
#define OPERAND(op) OPENRISC_OPERAND_/**/op
#endif
#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
/* The instruction table. */
static const CGEN_OPCODE openrisc_cgen_insn_opcode_table[MAX_INSNS] =
{
/* Special null first entry.
A `num' value of zero is thus invalid.
Also, the special `invalid' insn resides here. */
{ { 0, 0, 0, 0 }, {{0}}, 0, {0}},
/* l.j ${abs-26} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (ABS_26), 0 } },
& ifmt_l_j, { 0x0 }
},
/* l.jal ${abs-26} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (ABS_26), 0 } },
& ifmt_l_j, { 0x4000000 }
},
/* l.jr $rA */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), 0 } },
& ifmt_l_jr, { 0x14000000 }
},
/* l.jalr $rA */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), 0 } },
& ifmt_l_jr, { 0x14200000 }
},
/* l.bal ${disp-26} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (DISP_26), 0 } },
& ifmt_l_bal, { 0x8000000 }
},
/* l.bnf ${disp-26} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (DISP_26), 0 } },
& ifmt_l_bal, { 0xc000000 }
},
/* l.bf ${disp-26} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (DISP_26), 0 } },
& ifmt_l_bal, { 0x10000000 }
},
/* l.brk ${uimm-16} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (UIMM_16), 0 } },
& ifmt_l_jr, { 0x17000000 }
},
/* l.rfe $rA */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), 0 } },
& ifmt_l_jr, { 0x14400000 }
},
/* l.sys ${uimm-16} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (UIMM_16), 0 } },
& ifmt_l_jr, { 0x16000000 }
},
/* l.nop */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_l_jr, { 0x15000000 }
},
/* l.movhi $rD,$hi16 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (HI16), 0 } },
& ifmt_l_movhi, { 0x18000000 }
},
/* l.mfsr $rD,$rA */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), 0 } },
& ifmt_l_mfsr, { 0x1c000000 }
},
/* l.mtsr $rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_mtsr, { 0x40000000 }
},
/* l.lw $rD,${simm-16}($rA) */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (SIMM_16), '(', OP (RA), ')', 0 } },
& ifmt_l_lw, { 0x80000000 }
},
/* l.lbz $rD,${simm-16}($rA) */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (SIMM_16), '(', OP (RA), ')', 0 } },
& ifmt_l_lw, { 0x84000000 }
},
/* l.lbs $rD,${simm-16}($rA) */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (SIMM_16), '(', OP (RA), ')', 0 } },
& ifmt_l_lw, { 0x88000000 }
},
/* l.lhz $rD,${simm-16}($rA) */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (SIMM_16), '(', OP (RA), ')', 0 } },
& ifmt_l_lw, { 0x8c000000 }
},
/* l.lhs $rD,${simm-16}($rA) */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (SIMM_16), '(', OP (RA), ')', 0 } },
& ifmt_l_lw, { 0x90000000 }
},
/* l.sw ${ui16nc}($rA),$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (UI16NC), '(', OP (RA), ')', ',', OP (RB), 0 } },
& ifmt_l_sw, { 0xd4000000 }
},
/* l.sb ${ui16nc}($rA),$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (UI16NC), '(', OP (RA), ')', ',', OP (RB), 0 } },
& ifmt_l_sw, { 0xd8000000 }
},
/* l.sh ${ui16nc}($rA),$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (UI16NC), '(', OP (RA), ')', ',', OP (RB), 0 } },
& ifmt_l_sw, { 0xdc000000 }
},
/* l.sll $rD,$rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sll, { 0xe0000008 }
},
/* l.slli $rD,$rA,${uimm-5} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM_5), 0 } },
& ifmt_l_slli, { 0xb4000000 }
},
/* l.srl $rD,$rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sll, { 0xe0000028 }
},
/* l.srli $rD,$rA,${uimm-5} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM_5), 0 } },
& ifmt_l_slli, { 0xb4000020 }
},
/* l.sra $rD,$rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sll, { 0xe0000048 }
},
/* l.srai $rD,$rA,${uimm-5} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM_5), 0 } },
& ifmt_l_slli, { 0xb4000040 }
},
/* l.ror $rD,$rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sll, { 0xe0000088 }
},
/* l.rori $rD,$rA,${uimm-5} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (UIMM_5), 0 } },
& ifmt_l_slli, { 0xb4000080 }
},
/* l.add $rD,$rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_add, { 0xe0000000 }
},
/* l.addi $rD,$rA,$lo16 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (LO16), 0 } },
& ifmt_l_addi, { 0x94000000 }
},
/* l.sub $rD,$rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_add, { 0xe0000002 }
},
/* l.subi $rD,$rA,$lo16 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (LO16), 0 } },
& ifmt_l_addi, { 0x9c000000 }
},
/* l.and $rD,$rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_add, { 0xe0000003 }
},
/* l.andi $rD,$rA,$lo16 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (LO16), 0 } },
& ifmt_l_addi, { 0xa0000000 }
},
/* l.or $rD,$rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_add, { 0xe0000004 }
},
/* l.ori $rD,$rA,$lo16 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (LO16), 0 } },
& ifmt_l_addi, { 0xa4000000 }
},
/* l.xor $rD,$rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_add, { 0xe0000005 }
},
/* l.xori $rD,$rA,$lo16 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (LO16), 0 } },
& ifmt_l_addi, { 0xa8000000 }
},
/* l.mul $rD,$rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_add, { 0xe0000006 }
},
/* l.muli $rD,$rA,$lo16 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (LO16), 0 } },
& ifmt_l_addi, { 0xac000000 }
},
/* l.div $rD,$rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_add, { 0xe0000009 }
},
/* l.divu $rD,$rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RD), ',', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_add, { 0xe000000a }
},
/* l.sfgts $rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sfgts, { 0xe4c00000 }
},
/* l.sfgtu $rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sfgts, { 0xe4400000 }
},
/* l.sfges $rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sfgts, { 0xe4e00000 }
},
/* l.sfgeu $rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sfgts, { 0xe4600000 }
},
/* l.sflts $rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sfgts, { 0xe5000000 }
},
/* l.sfltu $rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sfgts, { 0xe4800000 }
},
/* l.sfles $rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sfgts, { 0xe5200000 }
},
/* l.sfleu $rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sfgts, { 0xe4a00000 }
},
/* l.sfgtsi $rA,${simm-16} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (SIMM_16), 0 } },
& ifmt_l_sfgtsi, { 0xb8c00000 }
},
/* l.sfgtui $rA,${uimm-16} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (UIMM_16), 0 } },
& ifmt_l_sfgtui, { 0xb8400000 }
},
/* l.sfgesi $rA,${simm-16} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (SIMM_16), 0 } },
& ifmt_l_sfgtsi, { 0xb8e00000 }
},
/* l.sfgeui $rA,${uimm-16} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (UIMM_16), 0 } },
& ifmt_l_sfgtui, { 0xb8600000 }
},
/* l.sfltsi $rA,${simm-16} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (SIMM_16), 0 } },
& ifmt_l_sfgtsi, { 0xb9000000 }
},
/* l.sfltui $rA,${uimm-16} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (UIMM_16), 0 } },
& ifmt_l_sfgtui, { 0xb8800000 }
},
/* l.sflesi $rA,${simm-16} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (SIMM_16), 0 } },
& ifmt_l_sfgtsi, { 0xb9200000 }
},
/* l.sfleui $rA,${uimm-16} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (UIMM_16), 0 } },
& ifmt_l_sfgtui, { 0xb8a00000 }
},
/* l.sfeq $rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sfgts, { 0xe4000000 }
},
/* l.sfeqi $rA,${simm-16} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (SIMM_16), 0 } },
& ifmt_l_sfgtsi, { 0xb8000000 }
},
/* l.sfne $rA,$rB */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (RB), 0 } },
& ifmt_l_sfgts, { 0xe4200000 }
},
/* l.sfnei $rA,${simm-16} */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (RA), ',', OP (SIMM_16), 0 } },
& ifmt_l_sfgtsi, { 0xb8200000 }
},
};
#undef A
#undef OPERAND
#undef MNEM
#undef OP
/* Formats for ALIAS macro-insns. */
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define F(f) & openrisc_cgen_ifld_table[OPENRISC_##f]
#else
#define F(f) & openrisc_cgen_ifld_table[OPENRISC_/**/f]
#endif
static const CGEN_IFMT ifmt_l_ret = {
32, 32, 0xffffffff, { { F (F_CLASS) }, { F (F_SUB) }, { F (F_OP3) }, { F (F_OP4) }, { F (F_R2) }, { F (F_UIMM16) }, { 0 } }
};
#undef F
/* Each non-simple macro entry points to an array of expansion possibilities. */
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define A(a) (1 << CGEN_INSN_##a)
#else
#define A(a) (1 << CGEN_INSN_/**/a)
#endif
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define OPERAND(op) OPENRISC_OPERAND_##op
#else
#define OPERAND(op) OPENRISC_OPERAND_/**/op
#endif
#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
/* The macro instruction table. */
static const CGEN_IBASE openrisc_cgen_macro_insn_table[] =
{
/* l.ret */
{
-1, "l-ret", "l.ret", 32,
{ 0|A(ALIAS), { (1<<MACH_BASE) } }
},
};
/* The macro instruction opcode table. */
static const CGEN_OPCODE openrisc_cgen_macro_insn_opcode_table[] =
{
/* l.ret */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_l_ret, { 0x140b0000 }
},
};
#undef A
#undef OPERAND
#undef MNEM
#undef OP
#ifndef CGEN_ASM_HASH_P
#define CGEN_ASM_HASH_P(insn) 1
#endif
#ifndef CGEN_DIS_HASH_P
#define CGEN_DIS_HASH_P(insn) 1
#endif
/* Return non-zero if INSN is to be added to the hash table.
Targets are free to override CGEN_{ASM,DIS}_HASH_P in the .opc file. */
static int
asm_hash_insn_p (insn)
const CGEN_INSN *insn;
{
return CGEN_ASM_HASH_P (insn);
}
static int
dis_hash_insn_p (insn)
const CGEN_INSN *insn;
{
/* If building the hash table and the NO-DIS attribute is present,
ignore. */
if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_NO_DIS))
return 0;
return CGEN_DIS_HASH_P (insn);
}
#ifndef CGEN_ASM_HASH
#define CGEN_ASM_HASH_SIZE 127
#ifdef CGEN_MNEMONIC_OPERANDS
#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE)
#else
#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) /*FIXME*/
#endif
#endif
/* It doesn't make much sense to provide a default here,
but while this is under development we do.
BUFFER is a pointer to the bytes of the insn, target order.
VALUE is the first base_insn_bitsize bits as an int in host order. */
#ifndef CGEN_DIS_HASH
#define CGEN_DIS_HASH_SIZE 256
#define CGEN_DIS_HASH(buf, value) (*(unsigned char *) (buf))
#endif
/* The result is the hash value of the insn.
Targets are free to override CGEN_{ASM,DIS}_HASH in the .opc file. */
static unsigned int
asm_hash_insn (mnem)
const char * mnem;
{
return CGEN_ASM_HASH (mnem);
}
/* BUF is a pointer to the bytes of the insn, target order.
VALUE is the first base_insn_bitsize bits as an int in host order. */
static unsigned int
dis_hash_insn (buf, value)
const char * buf;
CGEN_INSN_INT value;
{
return CGEN_DIS_HASH (buf, value);
}
/* Set the recorded length of the insn in the CGEN_FIELDS struct. */
static void
set_fields_bitsize (fields, size)
CGEN_FIELDS *fields;
int size;
{
CGEN_FIELDS_BITSIZE (fields) = size;
}
/* Function to call before using the operand instance table.
This plugs the opcode entries and macro instructions into the cpu table. */
void
openrisc_cgen_init_opcode_table (cd)
CGEN_CPU_DESC cd;
{
int i;
int num_macros = (sizeof (openrisc_cgen_macro_insn_table) /
sizeof (openrisc_cgen_macro_insn_table[0]));
const CGEN_IBASE *ib = & openrisc_cgen_macro_insn_table[0];
const CGEN_OPCODE *oc = & openrisc_cgen_macro_insn_opcode_table[0];
CGEN_INSN *insns = (CGEN_INSN *) xmalloc (num_macros * sizeof (CGEN_INSN));
memset (insns, 0, num_macros * sizeof (CGEN_INSN));
for (i = 0; i < num_macros; ++i)
{
insns[i].base = &ib[i];
insns[i].opcode = &oc[i];
}
cd->macro_insn_table.init_entries = insns;
cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE);
cd->macro_insn_table.num_init_entries = num_macros;
oc = & openrisc_cgen_insn_opcode_table[0];
insns = (CGEN_INSN *) cd->insn_table.init_entries;
for (i = 0; i < MAX_INSNS; ++i)
insns[i].opcode = &oc[i];
cd->sizeof_fields = sizeof (CGEN_FIELDS);
cd->set_fields_bitsize = set_fields_bitsize;
cd->asm_hash_p = asm_hash_insn_p;
cd->asm_hash = asm_hash_insn;
cd->asm_hash_size = CGEN_ASM_HASH_SIZE;
cd->dis_hash_p = dis_hash_insn_p;
cd->dis_hash = dis_hash_insn;
cd->dis_hash_size = CGEN_DIS_HASH_SIZE;
}

112
opcodes/openrisc-opc.h Normal file
View File

@ -0,0 +1,112 @@
/* Instruction opcode header for openrisc.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
This program 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.
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef OPENRISC_OPC_H
#define OPENRISC_OPC_H
/* -- opc.h */
#undef CGEN_DIS_HASH_SIZE
#define CGEN_DIS_HASH_SIZE 64
#undef CGEN_DIS_HASH
#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2)
/* -- */
/* Enum declaration for openrisc instruction types. */
typedef enum cgen_insn_type {
OPENRISC_INSN_INVALID, OPENRISC_INSN_L_J, OPENRISC_INSN_L_JAL, OPENRISC_INSN_L_JR
, OPENRISC_INSN_L_JALR, OPENRISC_INSN_L_BAL, OPENRISC_INSN_L_BNF, OPENRISC_INSN_L_BF
, OPENRISC_INSN_L_BRK, OPENRISC_INSN_L_RFE, OPENRISC_INSN_L_SYS, OPENRISC_INSN_L_NOP
, OPENRISC_INSN_L_MOVHI, OPENRISC_INSN_L_MFSR, OPENRISC_INSN_L_MTSR, OPENRISC_INSN_L_LW
, OPENRISC_INSN_L_LBZ, OPENRISC_INSN_L_LBS, OPENRISC_INSN_L_LHZ, OPENRISC_INSN_L_LHS
, OPENRISC_INSN_L_SW, OPENRISC_INSN_L_SB, OPENRISC_INSN_L_SH, OPENRISC_INSN_L_SLL
, OPENRISC_INSN_L_SLLI, OPENRISC_INSN_L_SRL, OPENRISC_INSN_L_SRLI, OPENRISC_INSN_L_SRA
, OPENRISC_INSN_L_SRAI, OPENRISC_INSN_L_ROR, OPENRISC_INSN_L_RORI, OPENRISC_INSN_L_ADD
, OPENRISC_INSN_L_ADDI, OPENRISC_INSN_L_SUB, OPENRISC_INSN_L_SUBI, OPENRISC_INSN_L_AND
, OPENRISC_INSN_L_ANDI, OPENRISC_INSN_L_OR, OPENRISC_INSN_L_ORI, OPENRISC_INSN_L_XOR
, OPENRISC_INSN_L_XORI, OPENRISC_INSN_L_MUL, OPENRISC_INSN_L_MULI, OPENRISC_INSN_L_DIV
, OPENRISC_INSN_L_DIVU, OPENRISC_INSN_L_SFGTS, OPENRISC_INSN_L_SFGTU, OPENRISC_INSN_L_SFGES
, OPENRISC_INSN_L_SFGEU, OPENRISC_INSN_L_SFLTS, OPENRISC_INSN_L_SFLTU, OPENRISC_INSN_L_SFLES
, OPENRISC_INSN_L_SFLEU, OPENRISC_INSN_L_SFGTSI, OPENRISC_INSN_L_SFGTUI, OPENRISC_INSN_L_SFGESI
, OPENRISC_INSN_L_SFGEUI, OPENRISC_INSN_L_SFLTSI, OPENRISC_INSN_L_SFLTUI, OPENRISC_INSN_L_SFLESI
, OPENRISC_INSN_L_SFLEUI, OPENRISC_INSN_L_SFEQ, OPENRISC_INSN_L_SFEQI, OPENRISC_INSN_L_SFNE
, OPENRISC_INSN_L_SFNEI
} CGEN_INSN_TYPE;
/* Index of `invalid' insn place holder. */
#define CGEN_INSN_INVALID OPENRISC_INSN_INVALID
/* Total number of insns in table. */
#define MAX_INSNS ((int) OPENRISC_INSN_L_SFNEI + 1)
/* This struct records data prior to insertion or after extraction. */
struct cgen_fields
{
int length;
long f_nil;
long f_anyof;
long f_class;
long f_sub;
long f_r1;
long f_r2;
long f_r3;
long f_simm16;
long f_uimm16;
long f_uimm5;
long f_hi16;
long f_lo16;
long f_op1;
long f_op2;
long f_op3;
long f_op4;
long f_op5;
long f_op6;
long f_op7;
long f_i16_1;
long f_i16_2;
long f_disp26;
long f_abs26;
long f_i16nc;
long f_f_15_8;
long f_f_10_3;
long f_f_4_1;
long f_f_7_3;
long f_f_10_7;
long f_f_10_11;
};
#define CGEN_INIT_PARSE(od) \
{\
}
#define CGEN_INIT_INSERT(od) \
{\
}
#define CGEN_INIT_EXTRACT(od) \
{\
}
#define CGEN_INIT_PRINT(od) \
{\
}
#endif /* OPENRISC_OPC_H */

View File

@ -69,6 +69,13 @@ mips16-opc.c
mips-dis.c
mips-opc.c
ns32k-dis.c
openrisc-asm.c
openrisc-desc.c
openrisc-desc.h
openrisc-dis.c
openrisc-ibld.c
openrisc-opc.c
openrisc-opc.h
pdp11-dis.c
pdp11-opc.c
pj-dis.c

View File

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2001-04-24 17:11+0100\n"
"POT-Creation-Date: 2001-04-27 15:23+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -60,7 +60,7 @@ msgstr ""
msgid "unrecognized keyword/register name"
msgstr ""
#: cgen-asm.c:332 fr30-ibld.c:172 m32r-ibld.c:172
#: cgen-asm.c:332 fr30-ibld.c:172 m32r-ibld.c:172 openrisc-ibld.c:172
#, c-format
msgid "operand out of range (%ld not between %ld and %ld)"
msgstr ""
@ -86,77 +86,78 @@ msgstr ""
msgid "Address 0x%x is out of bounds.\n"
msgstr ""
#: fr30-asm.c:305 m32r-asm.c:313
#: fr30-asm.c:305 m32r-asm.c:313 openrisc-asm.c:237
#, c-format
msgid "Unrecognized field %d while parsing.\n"
msgstr ""
#. We couldn't parse it.
#: fr30-asm.c:369 fr30-asm.c:373 fr30-asm.c:458 fr30-asm.c:552 m32r-asm.c:377
#: m32r-asm.c:381 m32r-asm.c:466 m32r-asm.c:560
#: m32r-asm.c:381 m32r-asm.c:466 m32r-asm.c:560 openrisc-asm.c:301
#: openrisc-asm.c:305 openrisc-asm.c:390 openrisc-asm.c:484
msgid "unrecognized instruction"
msgstr ""
#: fr30-asm.c:415 m32r-asm.c:423
#: fr30-asm.c:415 m32r-asm.c:423 openrisc-asm.c:347
#, c-format
msgid "syntax error (expected char `%c', found `%c')"
msgstr ""
#: fr30-asm.c:424 m32r-asm.c:432
#: fr30-asm.c:424 m32r-asm.c:432 openrisc-asm.c:356
#, c-format
msgid "syntax error (expected char `%c', found end of instruction)"
msgstr ""
#: fr30-asm.c:452 m32r-asm.c:460
#: fr30-asm.c:452 m32r-asm.c:460 openrisc-asm.c:384
msgid "junk at end of line"
msgstr ""
#: fr30-asm.c:563 m32r-asm.c:571
#: fr30-asm.c:563 m32r-asm.c:571 openrisc-asm.c:495
#, c-format
msgid "bad instruction `%.50s...'"
msgstr ""
#: fr30-asm.c:566 m32r-asm.c:574
#: fr30-asm.c:566 m32r-asm.c:574 openrisc-asm.c:498
#, c-format
msgid "bad instruction `%.50s'"
msgstr ""
#: fr30-dis.c:300 m32r-dis.c:239
#: fr30-dis.c:300 m32r-dis.c:239 openrisc-dis.c:130
#, c-format
msgid "Unrecognized field %d while printing insn.\n"
msgstr ""
#: fr30-ibld.c:156 m32r-ibld.c:156
#: fr30-ibld.c:156 m32r-ibld.c:156 openrisc-ibld.c:156
#, c-format
msgid "operand out of range (%lu not between 0 and %lu)"
msgstr ""
#: fr30-ibld.c:702 m32r-ibld.c:631
#: fr30-ibld.c:702 m32r-ibld.c:631 openrisc-ibld.c:605
#, c-format
msgid "Unrecognized field %d while building insn.\n"
msgstr ""
#: fr30-ibld.c:906 m32r-ibld.c:761
#: fr30-ibld.c:906 m32r-ibld.c:761 openrisc-ibld.c:704
#, c-format
msgid "Unrecognized field %d while decoding insn.\n"
msgstr ""
#: fr30-ibld.c:1050 m32r-ibld.c:866
#: fr30-ibld.c:1050 m32r-ibld.c:866 openrisc-ibld.c:779
#, c-format
msgid "Unrecognized field %d while getting int operand.\n"
msgstr ""
#: fr30-ibld.c:1179 m32r-ibld.c:956
#: fr30-ibld.c:1179 m32r-ibld.c:956 openrisc-ibld.c:839
#, c-format
msgid "Unrecognized field %d while getting vma operand.\n"
msgstr ""
#: fr30-ibld.c:1308 m32r-ibld.c:1049
#: fr30-ibld.c:1308 m32r-ibld.c:1049 openrisc-ibld.c:903
#, c-format
msgid "Unrecognized field %d while setting int operand.\n"
msgstr ""
#: fr30-ibld.c:1430 m32r-ibld.c:1135
#: fr30-ibld.c:1430 m32r-ibld.c:1135 openrisc-ibld.c:960
#, c-format
msgid "Unrecognized field %d while setting vma operand.\n"
msgstr ""