mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 10:35:12 +08:00
* iq2000-asm.c: New file.
* iq2000-desc.c: Likewise. * iq2000-desc.h: Likewise. * iq2000-dis.c: Likewise. * iq2000-ibld.c: Likewise. * iq2000-opc.c: Likewise. * iq2000-opc.h: Likewise. * Makefile.am (HFILES): Add iq2000-desc.h, iq2000-opc.h. (CFILES): Add iq2000-asm.c, iq2000-desc.c, iq2000-dis.c, iq2000-ibld.c, iq2000-opc.c. (ALL_MACHINES): Add iq2000-asm.lo, iq2000-desc.lo, iq2000-dis.lo, iq2000-ibld.lo, iq2000-opc.lo. (CLEANFILES): Add stamp-iq2000. (IQ2000_DEPS): New macro. (stamp-iq2000): New target. * Makefile.in: Regenerate. * configure.in: Handle bfd_iq2000_arch. * configure: Regenerate.
This commit is contained in:
parent
8ccd593be0
commit
47b1a55a55
@ -1,3 +1,25 @@
|
||||
2002-01-02 Ben Elliston <bje@redhat.com>
|
||||
Jeff Johnston <jjohnstn@redhat.com>
|
||||
|
||||
* iq2000-asm.c: New file.
|
||||
* iq2000-desc.c: Likewise.
|
||||
* iq2000-desc.h: Likewise.
|
||||
* iq2000-dis.c: Likewise.
|
||||
* iq2000-ibld.c: Likewise.
|
||||
* iq2000-opc.c: Likewise.
|
||||
* iq2000-opc.h: Likewise.
|
||||
* Makefile.am (HFILES): Add iq2000-desc.h, iq2000-opc.h.
|
||||
(CFILES): Add iq2000-asm.c, iq2000-desc.c, iq2000-dis.c,
|
||||
iq2000-ibld.c, iq2000-opc.c.
|
||||
(ALL_MACHINES): Add iq2000-asm.lo, iq2000-desc.lo, iq2000-dis.lo,
|
||||
iq2000-ibld.lo, iq2000-opc.lo.
|
||||
(CLEANFILES): Add stamp-iq2000.
|
||||
(IQ2000_DEPS): New macro.
|
||||
(stamp-iq2000): New target.
|
||||
* Makefile.in: Regenerate.
|
||||
* configure.in: Handle bfd_iq2000_arch.
|
||||
* configure: Regenerate.
|
||||
|
||||
2003-01-02 Chris Demetriou <cgd@broadcom.com>
|
||||
|
||||
* mips-dis.c (print_insn_args): Use position extracted by "+A"
|
||||
|
@ -31,6 +31,7 @@ HFILES = \
|
||||
ia64-asmtab.h \
|
||||
ia64-opc.h \
|
||||
ip2k-desc.h ip2k-opc.h \
|
||||
iq2000-desc.h iq2000-opc.h \
|
||||
m32r-desc.h m32r-opc.h \
|
||||
mcore-opc.h \
|
||||
openrisc-desc.h openrisc-opc.h \
|
||||
@ -96,6 +97,11 @@ CFILES = \
|
||||
ip2k-dis.c \
|
||||
ip2k-ibld.c \
|
||||
ip2k-opc.c \
|
||||
iq2000-asm.c \
|
||||
iq2000-desc.c \
|
||||
iq2000-dis.c \
|
||||
iq2000-ibld.c \
|
||||
iq2000-opc.c \
|
||||
m32r-asm.c \
|
||||
m32r-desc.c \
|
||||
m32r-dis.c \
|
||||
@ -201,6 +207,11 @@ ALL_MACHINES = \
|
||||
ip2k-dis.lo \
|
||||
ip2k-ibld.lo \
|
||||
ip2k-opc.lo \
|
||||
iq2000-asm.lo \
|
||||
iq2000-desc.lo \
|
||||
iq2000-dis.lo \
|
||||
iq2000-ibld.lo \
|
||||
iq2000-opc.lo \
|
||||
m32r-asm.lo \
|
||||
m32r-desc.lo \
|
||||
m32r-dis.lo \
|
||||
@ -326,7 +337,7 @@ uninstall_libopcodes:
|
||||
|
||||
CLEANFILES = \
|
||||
stamp-ip2k stamp-m32r stamp-fr30 stamp-frv stamp-openrisc \
|
||||
stamp-xstormy16 \
|
||||
stamp-iq2000 stamp-xstormy16 \
|
||||
libopcodes.a stamp-lib dep.sed DEP DEPA DEP1 DEP2
|
||||
|
||||
|
||||
@ -350,6 +361,7 @@ M32R_DEPS = stamp-m32r
|
||||
FR30_DEPS = stamp-fr30
|
||||
FRV_DEPS = stamp-frv
|
||||
OPENRISC_DEPS = stamp-openrisc
|
||||
IQ2000_DEPS = stamp-iq2000
|
||||
XSTORMY16_DEPS = stamp-xstormy16
|
||||
else
|
||||
IP2K_DEPS =
|
||||
@ -357,6 +369,7 @@ M32R_DEPS =
|
||||
FR30_DEPS =
|
||||
FRV_DEPS =
|
||||
OPENRISC_DEPS =
|
||||
IQ2000_DEPS =
|
||||
XSTORMY16_DEPS =
|
||||
endif
|
||||
|
||||
@ -401,6 +414,12 @@ $(srcdir)/openrisc-desc.h $(srcdir)/openrisc-desc.c $(srcdir)/openrisc-opc.h $(s
|
||||
stamp-openrisc: $(CGENDEPS) $(CPUDIR)/openrisc.cpu $(CPUDIR)/openrisc.opc
|
||||
$(MAKE) run-cgen arch=openrisc prefix=openrisc options= extrafiles=
|
||||
|
||||
$(srcdir)/iq2000-desc.h $(srcdir)/iq2000-desc.c $(srcdir)/iq2000-opc.h $(srcdir)/iq2000-opc.c $(srcdir)/iq2000-ibld.c $(srcdir)/iq2000-asm.c $(srcdir)/iq2000-dis.c: $(IQ2000_DEPS)
|
||||
@true
|
||||
stamp-iq2000: $(CGENDEPS) $(CPUDIR)/iq2000.cpu $(CPUDIR)/iq2000.opc \
|
||||
$(CPUDIR)/iq2000m.cpu $(CPUDIR)/iq10.cpu
|
||||
$(MAKE) run-cgen arch=iq2000 prefix=iq2000 options= extrafiles=
|
||||
|
||||
$(srcdir)/xstormy16-desc.h $(srcdir)/xstormy16-desc.c $(srcdir)/xstormy16-opc.h $(srcdir)/xstormy16-opc.c $(srcdir)/xstormy16-ibld.c $(srcdir)/xstormy16-asm.c $(srcdir)/xstormy16-dis.c: $(XSTORMY16_DEPS)
|
||||
@true
|
||||
stamp-xstormy16: $(CGENDEPS) $(CPUDIR)/xstormy16.cpu $(CPUDIR)/xstormy16.opc
|
||||
|
@ -141,6 +141,7 @@ HFILES = \
|
||||
ia64-asmtab.h \
|
||||
ia64-opc.h \
|
||||
ip2k-desc.h ip2k-opc.h \
|
||||
iq2000-desc.h iq2000-opc.h \
|
||||
m32r-desc.h m32r-opc.h \
|
||||
mcore-opc.h \
|
||||
openrisc-desc.h openrisc-opc.h \
|
||||
@ -207,6 +208,11 @@ CFILES = \
|
||||
ip2k-dis.c \
|
||||
ip2k-ibld.c \
|
||||
ip2k-opc.c \
|
||||
iq2000-asm.c \
|
||||
iq2000-desc.c \
|
||||
iq2000-dis.c \
|
||||
iq2000-ibld.c \
|
||||
iq2000-opc.c \
|
||||
m32r-asm.c \
|
||||
m32r-desc.c \
|
||||
m32r-dis.c \
|
||||
@ -313,6 +319,11 @@ ALL_MACHINES = \
|
||||
ip2k-dis.lo \
|
||||
ip2k-ibld.lo \
|
||||
ip2k-opc.lo \
|
||||
iq2000-asm.lo \
|
||||
iq2000-desc.lo \
|
||||
iq2000-dis.lo \
|
||||
iq2000-ibld.lo \
|
||||
iq2000-opc.lo \
|
||||
m32r-asm.lo \
|
||||
m32r-desc.lo \
|
||||
m32r-dis.lo \
|
||||
@ -392,7 +403,7 @@ noinst_LIBRARIES = libopcodes.a
|
||||
POTFILES = $(HFILES) $(CFILES)
|
||||
|
||||
CLEANFILES = \
|
||||
stamp-ip2k stamp-m32r stamp-fr30 stamp-frv stamp-openrisc \
|
||||
stamp-ip2k stamp-iq2000 stamp-m32r stamp-fr30 stamp-frv stamp-openrisc \
|
||||
stamp-xstormy16 \
|
||||
libopcodes.a stamp-lib dep.sed DEP DEPA DEP1 DEP2
|
||||
|
||||
@ -413,6 +424,8 @@ CGENDEPS = \
|
||||
CGEN_CPUS = fr30 frv ip2k m32r openrisc xstormy16
|
||||
@CGEN_MAINT_TRUE@IP2K_DEPS = @CGEN_MAINT_TRUE@stamp-ip2k
|
||||
@CGEN_MAINT_FALSE@IP2K_DEPS =
|
||||
@CGEN_MAINT_TRUE@IQ2000_DEPS = @CGEN_MAINT_TRUE@stamp-ip2000
|
||||
@CGEN_MAINT_FALSE@IQ2000_DEPS =
|
||||
@CGEN_MAINT_TRUE@M32R_DEPS = @CGEN_MAINT_TRUE@stamp-m32r
|
||||
@CGEN_MAINT_FALSE@M32R_DEPS =
|
||||
@CGEN_MAINT_TRUE@FR30_DEPS = @CGEN_MAINT_TRUE@stamp-fr30
|
||||
@ -877,6 +890,12 @@ $(srcdir)/ip2k-desc.h $(srcdir)/ip2k-desc.c $(srcdir)/ip2k-opc.h $(srcdir)/ip2k-
|
||||
stamp-ip2k: $(CGENDEPS) $(CPUDIR)/ip2k.cpu $(CPUDIR)/ip2k.opc
|
||||
$(MAKE) run-cgen arch=ip2k prefix=ip2k options= extrafiles=
|
||||
|
||||
$(srcdir)/iq2000-desc.h $(srcdir)/iq2000-desc.c $(srcdir)/iq2000-opc.h $(srcdir)/iq2000-opc.c $(srcdir)/iq2000-ibld.c $(srcdir)/iq2000-asm.c $(srcdir)/iq2000-dis.c: $(IQ2000_DEPS)
|
||||
@true
|
||||
stamp-iq2000: $(CGENDEPS) $(CPUDIR)/iq2000.cpu $(CPUDIR)/iq2000.opc \
|
||||
$(CPUDIR)/iq2000m.cpu $(CPUDIR)/iq10.cpu
|
||||
$(MAKE) run-cgen arch=iq2000 prefix=iq2000 options= extrafiles=
|
||||
|
||||
$(srcdir)/m32r-desc.h $(srcdir)/m32r-desc.c $(srcdir)/m32r-opc.h $(srcdir)/m32r-opc.c $(srcdir)/m32r-ibld.c $(srcdir)/m32r-opinst.c $(srcdir)/m32r-asm.c $(srcdir)/m32r-dis.c: $(M32R_DEPS)
|
||||
@true
|
||||
stamp-m32r: $(CGENDEPS) $(CPUDIR)/m32r.cpu $(CPUDIR)/m32r.opc
|
||||
@ -1114,6 +1133,23 @@ ip2k-ibld.lo: ip2k-ibld.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
ip2k-opc.lo: ip2k-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h ip2k-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
ip2k-opc.h $(INCDIR)/libiberty.h
|
||||
iq2000-asm.lo: iq2000-asm.c sysdep.h config.h $(BFD_H) \
|
||||
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h iq2000-desc.h \
|
||||
$(INCDIR)/opcode/cgen.h iq2000-opc.h opintl.h
|
||||
iq2000-desc.lo: iq2000-desc.c sysdep.h config.h $(BFD_H) \
|
||||
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h iq2000-desc.h \
|
||||
$(INCDIR)/opcode/cgen.h iq2000-opc.h opintl.h
|
||||
iq2000-dis.lo: iq2000-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
|
||||
$(BFD_H) $(INCDIR)/ansidecl.h \
|
||||
$(INCDIR)/symcat.h iq2000-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
iq2000-opc.h opintl.h
|
||||
iq2000-ibld.lo: iq2000-ibld.c sysdep.h config.h $(INCDIR)/dis-asm.h \
|
||||
$(BFD_H) $(INCDIR)/ansidecl.h \
|
||||
$(INCDIR)/symcat.h iq2000-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
iq2000-opc.h opintl.h
|
||||
iq2000-opc.lo: iq2000-opc.c sysdep.h config.h $(BFD_H) \
|
||||
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h iq2000-desc.h \
|
||||
$(INCDIR)/opcode/cgen.h iq2000-opc.h
|
||||
m32r-asm.lo: m32r-asm.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
m32r-opc.h opintl.h $(INCDIR)/xregex.h $(INCDIR)/xregex2.h \
|
||||
|
1
opcodes/configure
vendored
1
opcodes/configure
vendored
@ -4615,6 +4615,7 @@ if test x${all_targets} = xfalse ; then
|
||||
bfd_i960_arch) ta="$ta i960-dis.lo" ;;
|
||||
bfd_ia64_arch) ta="$ta ia64-dis.lo ia64-opc.lo" ;;
|
||||
bfd_ip2k_arch) ta="$ta ip2k-asm.lo ip2k-desc.lo ip2k-dis.lo ip2k-ibld.lo ip2k-opc.lo" using_cgen=yes ;;
|
||||
bfd_iq2000_arch) ta="$ta iq2000-asm.lo iq2000-desc.lo iq2000-dis.lo iq2000-ibld.lo iq2000-opc.lo" using_cgen=yes ;;
|
||||
bfd_m32r_arch) ta="$ta m32r-asm.lo m32r-desc.lo m32r-dis.lo m32r-ibld.lo m32r-opc.lo m32r-opinst.lo" using_cgen=yes ;;
|
||||
bfd_m68hc11_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
|
||||
bfd_m68hc12_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
|
||||
|
@ -190,6 +190,7 @@ if test x${all_targets} = xfalse ; then
|
||||
bfd_i960_arch) ta="$ta i960-dis.lo" ;;
|
||||
bfd_ia64_arch) ta="$ta ia64-dis.lo ia64-opc.lo" ;;
|
||||
bfd_ip2k_arch) ta="$ta ip2k-asm.lo ip2k-desc.lo ip2k-dis.lo ip2k-ibld.lo ip2k-opc.lo" using_cgen=yes ;;
|
||||
bfd_iq2000_arch) ta="$ta iq2000-asm.lo iq2000-desc.lo iq2000-dis.lo iq2000-ibld.lo iq2000-opc.lo" using_cgen=yes ;;
|
||||
bfd_m32r_arch) ta="$ta m32r-asm.lo m32r-desc.lo m32r-dis.lo m32r-ibld.lo m32r-opc.lo m32r-opinst.lo" using_cgen=yes ;;
|
||||
bfd_m68hc11_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
|
||||
bfd_m68hc12_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
|
||||
|
@ -70,6 +70,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#define ARCH_xstormy16
|
||||
#define ARCH_z8k
|
||||
#define ARCH_frv
|
||||
#define ARCH_iq2000
|
||||
#define INCLUDE_SHMEDIA
|
||||
#endif
|
||||
|
||||
@ -359,6 +360,11 @@ disassembler (abfd)
|
||||
case bfd_arch_frv:
|
||||
disassemble = print_insn_frv;
|
||||
break;
|
||||
#endif
|
||||
#ifdef ARCH_iq2000
|
||||
case bfd_arch_iq2000:
|
||||
disassemble = print_insn_iq2000;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
|
891
opcodes/iq2000-asm.c
Normal file
891
opcodes/iq2000-asm.c
Normal file
@ -0,0 +1,891 @@
|
||||
/* 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 <stdio.h>
|
||||
#include "ansidecl.h"
|
||||
#include "bfd.h"
|
||||
#include "symcat.h"
|
||||
#include "iq2000-desc.h"
|
||||
#include "iq2000-opc.h"
|
||||
#include "opintl.h"
|
||||
#include "xregex.h"
|
||||
#include "libiberty.h"
|
||||
#include "safe-ctype.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 */
|
||||
static const char * parse_mimm PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
|
||||
static const char * parse_imm PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
|
||||
static const char * parse_hi16 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
|
||||
static const char * parse_lo16 PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
|
||||
|
||||
/* Special check to ensure that instruction exists for given machine */
|
||||
int
|
||||
iq2000_cgen_insn_supported (cd, insn)
|
||||
CGEN_CPU_DESC cd;
|
||||
CGEN_INSN *insn;
|
||||
{
|
||||
int machs = cd->machs;
|
||||
|
||||
return ((CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH) & machs) != 0);
|
||||
}
|
||||
|
||||
static int iq2000_cgen_isa_register (strp)
|
||||
const char **strp;
|
||||
{
|
||||
int len;
|
||||
int ch1, ch2;
|
||||
if (**strp == 'r' || **strp == 'R')
|
||||
{
|
||||
len = strlen (*strp);
|
||||
if (len == 2)
|
||||
{
|
||||
ch1 = (*strp)[1];
|
||||
if ('0' <= ch1 && ch1 <= '9')
|
||||
return 1;
|
||||
}
|
||||
else if (len == 3)
|
||||
{
|
||||
ch1 = (*strp)[1];
|
||||
ch2 = (*strp)[2];
|
||||
if (('1' <= ch1 && ch1 <= '2') && ('0' <= ch2 && ch2 <= '9'))
|
||||
return 1;
|
||||
if ('3' == ch1 && (ch2 == '0' || ch2 == '1'))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (**strp == '%' && tolower((*strp)[1]) != 'l' && tolower((*strp)[1]) != 'h')
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Handle negated literal. */
|
||||
|
||||
static const char *
|
||||
parse_mimm (cd, strp, opindex, valuep)
|
||||
CGEN_CPU_DESC cd;
|
||||
const char **strp;
|
||||
int opindex;
|
||||
long *valuep;
|
||||
{
|
||||
const char *errmsg;
|
||||
long value;
|
||||
|
||||
/* Verify this isn't a register */
|
||||
if (iq2000_cgen_isa_register (strp))
|
||||
errmsg = _("immediate value cannot be register");
|
||||
else
|
||||
{
|
||||
long value;
|
||||
|
||||
errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
|
||||
if (errmsg == NULL)
|
||||
{
|
||||
long x = (-value) & 0xFFFF0000;
|
||||
if (x != 0 && x != 0xFFFF0000)
|
||||
errmsg = _("immediate value out of range");
|
||||
else
|
||||
*valuep = (-value & 0xFFFF);
|
||||
}
|
||||
}
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
/* Handle signed/unsigned literal. */
|
||||
|
||||
static const char *
|
||||
parse_imm (cd, strp, opindex, valuep)
|
||||
CGEN_CPU_DESC cd;
|
||||
const char **strp;
|
||||
int opindex;
|
||||
unsigned long *valuep;
|
||||
{
|
||||
const char *errmsg;
|
||||
long value;
|
||||
|
||||
if (iq2000_cgen_isa_register (strp))
|
||||
errmsg = _("immediate value cannot be register");
|
||||
else
|
||||
{
|
||||
long value;
|
||||
|
||||
errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
|
||||
if (errmsg == NULL)
|
||||
{
|
||||
long x = value & 0xFFFF0000;
|
||||
if (x != 0 && x != 0xFFFF0000)
|
||||
errmsg = _("immediate value out of range");
|
||||
else
|
||||
*valuep = (value & 0xFFFF);
|
||||
}
|
||||
}
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
/* Handle iq10 21-bit jmp offset. */
|
||||
|
||||
static const char *
|
||||
parse_jtargq10 (cd, strp, opindex, reloc, type_addr, valuep)
|
||||
CGEN_CPU_DESC cd;
|
||||
const char **strp;
|
||||
int opindex;
|
||||
int reloc;
|
||||
enum cgen_parse_operand_result *type_addr;
|
||||
unsigned long *valuep;
|
||||
{
|
||||
const char *errmsg;
|
||||
bfd_vma value;
|
||||
enum cgen_parse_operand_result result_type = CGEN_PARSE_OPERAND_RESULT_NUMBER;
|
||||
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_OFFSET_21,
|
||||
&result_type, &value);
|
||||
if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
{
|
||||
/* check value is within 23-bits (remembering that 2-bit shift right will occur) */
|
||||
if (value > 0x7fffff)
|
||||
return _("21-bit offset out of range");
|
||||
}
|
||||
*valuep = (value & 0x7FFFFF);
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
/* Handle high(). */
|
||||
|
||||
static const char *
|
||||
parse_hi16 (cd, strp, opindex, valuep)
|
||||
CGEN_CPU_DESC cd;
|
||||
const char **strp;
|
||||
int opindex;
|
||||
unsigned long *valuep;
|
||||
{
|
||||
if (strncasecmp (*strp, "%hi(", 4) == 0)
|
||||
{
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
const char *errmsg;
|
||||
|
||||
*strp += 4;
|
||||
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)
|
||||
{
|
||||
/* if value has top-bit of %lo on, then it will
|
||||
sign-propagate and so we compensate by adding
|
||||
1 to the resultant %hi value */
|
||||
if (value & 0x8000)
|
||||
value += 0x10000;
|
||||
value >>= 16;
|
||||
}
|
||||
*valuep = value;
|
||||
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
/* we add %uhi in case a user just wants the high 16-bits or is using
|
||||
an insn like ori for %lo which does not sign-propagate */
|
||||
if (strncasecmp (*strp, "%uhi(", 5) == 0)
|
||||
{
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
const char *errmsg;
|
||||
|
||||
*strp += 5;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_UHI16,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return _("missing `)'");
|
||||
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
{
|
||||
value >>= 16;
|
||||
}
|
||||
*valuep = value;
|
||||
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return parse_imm (cd, strp, opindex, valuep);
|
||||
}
|
||||
|
||||
/* Handle %lo in a signed context.
|
||||
The signedness of the value doesn't matter to %lo(), but this also
|
||||
handles the case where %lo() isn't present. */
|
||||
|
||||
static const char *
|
||||
parse_lo16 (cd, strp, opindex, valuep)
|
||||
CGEN_CPU_DESC cd;
|
||||
const char **strp;
|
||||
int opindex;
|
||||
long *valuep;
|
||||
{
|
||||
if (strncasecmp (*strp, "%lo(", 4) == 0)
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
*strp += 4;
|
||||
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 = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return parse_imm (cd, strp, opindex, valuep);
|
||||
}
|
||||
|
||||
/* Handle %lo in a negated signed context.
|
||||
The signedness of the value doesn't matter to %lo(), but this also
|
||||
handles the case where %lo() isn't present. */
|
||||
|
||||
static const char *
|
||||
parse_mlo16 (cd, strp, opindex, valuep)
|
||||
CGEN_CPU_DESC cd;
|
||||
const char **strp;
|
||||
int opindex;
|
||||
long *valuep;
|
||||
{
|
||||
if (strncasecmp (*strp, "%lo(", 4) == 0)
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
*strp += 4;
|
||||
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 = (-value) & 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return parse_mimm (cd, strp, opindex, valuep);
|
||||
}
|
||||
|
||||
/* -- */
|
||||
|
||||
const char * iq2000_cgen_parse_operand
|
||||
PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *));
|
||||
|
||||
/* 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 *
|
||||
iq2000_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 ATTRIBUTE_UNUSED;
|
||||
|
||||
switch (opindex)
|
||||
{
|
||||
case IQ2000_OPERAND_BASE :
|
||||
errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rs);
|
||||
break;
|
||||
case IQ2000_OPERAND_BASEOFF :
|
||||
{
|
||||
bfd_vma value;
|
||||
errmsg = cgen_parse_address (cd, strp, IQ2000_OPERAND_BASEOFF, 0, NULL, & value);
|
||||
fields->f_imm = value;
|
||||
}
|
||||
break;
|
||||
case IQ2000_OPERAND_BITNUM :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_BITNUM, &fields->f_rt);
|
||||
break;
|
||||
case IQ2000_OPERAND_BYTECOUNT :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_BYTECOUNT, &fields->f_bytecount);
|
||||
break;
|
||||
case IQ2000_OPERAND_CAM_Y :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_CAM_Y, &fields->f_cam_y);
|
||||
break;
|
||||
case IQ2000_OPERAND_CAM_Z :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_CAM_Z, &fields->f_cam_z);
|
||||
break;
|
||||
case IQ2000_OPERAND_CM_3FUNC :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_CM_3FUNC, &fields->f_cm_3func);
|
||||
break;
|
||||
case IQ2000_OPERAND_CM_3Z :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_CM_3Z, &fields->f_cm_3z);
|
||||
break;
|
||||
case IQ2000_OPERAND_CM_4FUNC :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_CM_4FUNC, &fields->f_cm_4func);
|
||||
break;
|
||||
case IQ2000_OPERAND_CM_4Z :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_CM_4Z, &fields->f_cm_4z);
|
||||
break;
|
||||
case IQ2000_OPERAND_COUNT :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_COUNT, &fields->f_count);
|
||||
break;
|
||||
case IQ2000_OPERAND_EXECODE :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_EXECODE, &fields->f_excode);
|
||||
break;
|
||||
case IQ2000_OPERAND_HI16 :
|
||||
errmsg = parse_hi16 (cd, strp, IQ2000_OPERAND_HI16, &fields->f_imm);
|
||||
break;
|
||||
case IQ2000_OPERAND_IMM :
|
||||
errmsg = parse_imm (cd, strp, IQ2000_OPERAND_IMM, &fields->f_imm);
|
||||
break;
|
||||
case IQ2000_OPERAND_INDEX :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_INDEX, &fields->f_index);
|
||||
break;
|
||||
case IQ2000_OPERAND_JMPTARG :
|
||||
{
|
||||
bfd_vma value;
|
||||
errmsg = cgen_parse_address (cd, strp, IQ2000_OPERAND_JMPTARG, 0, NULL, & value);
|
||||
fields->f_jtarg = value;
|
||||
}
|
||||
break;
|
||||
case IQ2000_OPERAND_JMPTARGQ10 :
|
||||
{
|
||||
bfd_vma value;
|
||||
errmsg = parse_jtargq10 (cd, strp, IQ2000_OPERAND_JMPTARGQ10, 0, NULL, & value);
|
||||
fields->f_jtargq10 = value;
|
||||
}
|
||||
break;
|
||||
case IQ2000_OPERAND_LO16 :
|
||||
errmsg = parse_lo16 (cd, strp, IQ2000_OPERAND_LO16, &fields->f_imm);
|
||||
break;
|
||||
case IQ2000_OPERAND_MASK :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_MASK, &fields->f_mask);
|
||||
break;
|
||||
case IQ2000_OPERAND_MASKL :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_MASKL, &fields->f_maskl);
|
||||
break;
|
||||
case IQ2000_OPERAND_MASKQ10 :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_MASKQ10, &fields->f_maskq10);
|
||||
break;
|
||||
case IQ2000_OPERAND_MASKR :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_MASKR, &fields->f_rs);
|
||||
break;
|
||||
case IQ2000_OPERAND_MLO16 :
|
||||
errmsg = parse_mlo16 (cd, strp, IQ2000_OPERAND_MLO16, &fields->f_imm);
|
||||
break;
|
||||
case IQ2000_OPERAND_OFFSET :
|
||||
{
|
||||
bfd_vma value;
|
||||
errmsg = cgen_parse_address (cd, strp, IQ2000_OPERAND_OFFSET, 0, NULL, & value);
|
||||
fields->f_offset = value;
|
||||
}
|
||||
break;
|
||||
case IQ2000_OPERAND_RD :
|
||||
errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rd);
|
||||
break;
|
||||
case IQ2000_OPERAND_RD_RS :
|
||||
errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rd_rs);
|
||||
break;
|
||||
case IQ2000_OPERAND_RD_RT :
|
||||
errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rd_rt);
|
||||
break;
|
||||
case IQ2000_OPERAND_RS :
|
||||
errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rs);
|
||||
break;
|
||||
case IQ2000_OPERAND_RT :
|
||||
errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rt);
|
||||
break;
|
||||
case IQ2000_OPERAND_RT_RS :
|
||||
errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rt_rs);
|
||||
break;
|
||||
case IQ2000_OPERAND_SHAMT :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_SHAMT, &fields->f_shamt);
|
||||
break;
|
||||
|
||||
default :
|
||||
/* xgettext:c-format */
|
||||
fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
|
||||
abort ();
|
||||
}
|
||||
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
cgen_parse_fn * const iq2000_cgen_parse_handlers[] =
|
||||
{
|
||||
parse_insn_normal,
|
||||
};
|
||||
|
||||
void
|
||||
iq2000_cgen_init_asm (cd)
|
||||
CGEN_CPU_DESC cd;
|
||||
{
|
||||
iq2000_cgen_init_opcode_table (cd);
|
||||
iq2000_cgen_init_ibld_table (cd);
|
||||
cd->parse_handlers = & iq2000_cgen_parse_handlers[0];
|
||||
cd->parse_operand = iq2000_cgen_parse_operand;
|
||||
#ifdef CGEN_ASM_INIT_HOOK
|
||||
CGEN_ASM_INIT_HOOK
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Regex construction routine.
|
||||
|
||||
This translates an opcode syntax string into a regex string,
|
||||
by replacing any non-character syntax element (such as an
|
||||
opcode) with the pattern '.*'
|
||||
|
||||
It then compiles the regex and stores it in the opcode, for
|
||||
later use by iq2000_cgen_assemble_insn
|
||||
|
||||
Returns NULL for success, an error message for failure. */
|
||||
|
||||
char *
|
||||
iq2000_cgen_build_insn_regex (insn)
|
||||
CGEN_INSN *insn;
|
||||
{
|
||||
CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
|
||||
const char *mnem = CGEN_INSN_MNEMONIC (insn);
|
||||
char rxbuf[CGEN_MAX_RX_ELEMENTS];
|
||||
char *rx = rxbuf;
|
||||
const CGEN_SYNTAX_CHAR_TYPE *syn;
|
||||
int reg_err;
|
||||
|
||||
syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
|
||||
|
||||
/* Mnemonics come first in the syntax string. */
|
||||
if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
|
||||
return _("missing mnemonic in syntax string");
|
||||
++syn;
|
||||
|
||||
/* Generate a case sensitive regular expression that emulates case
|
||||
insensitive matching in the "C" locale. We cannot generate a case
|
||||
insensitive regular expression because in Turkish locales, 'i' and 'I'
|
||||
are not equal modulo case conversion. */
|
||||
|
||||
/* Copy the literal mnemonic out of the insn. */
|
||||
for (; *mnem; mnem++)
|
||||
{
|
||||
char c = *mnem;
|
||||
|
||||
if (ISALPHA (c))
|
||||
{
|
||||
*rx++ = '[';
|
||||
*rx++ = TOLOWER (c);
|
||||
*rx++ = TOUPPER (c);
|
||||
*rx++ = ']';
|
||||
}
|
||||
else
|
||||
*rx++ = c;
|
||||
}
|
||||
|
||||
/* Copy any remaining literals from the syntax string into the rx. */
|
||||
for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
|
||||
{
|
||||
if (CGEN_SYNTAX_CHAR_P (* syn))
|
||||
{
|
||||
char c = CGEN_SYNTAX_CHAR (* syn);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
/* Escape any regex metacharacters in the syntax. */
|
||||
case '.': case '[': case '\\':
|
||||
case '*': case '^': case '$':
|
||||
|
||||
#ifdef CGEN_ESCAPE_EXTENDED_REGEX
|
||||
case '?': case '{': case '}':
|
||||
case '(': case ')': case '*':
|
||||
case '|': case '+': case ']':
|
||||
#endif
|
||||
*rx++ = '\\';
|
||||
*rx++ = c;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (ISALPHA (c))
|
||||
{
|
||||
*rx++ = '[';
|
||||
*rx++ = TOLOWER (c);
|
||||
*rx++ = TOUPPER (c);
|
||||
*rx++ = ']';
|
||||
}
|
||||
else
|
||||
*rx++ = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Replace non-syntax fields with globs. */
|
||||
*rx++ = '.';
|
||||
*rx++ = '*';
|
||||
}
|
||||
}
|
||||
|
||||
/* Trailing whitespace ok. */
|
||||
* rx++ = '[';
|
||||
* rx++ = ' ';
|
||||
* rx++ = '\t';
|
||||
* rx++ = ']';
|
||||
* rx++ = '*';
|
||||
|
||||
/* But anchor it after that. */
|
||||
* rx++ = '$';
|
||||
* rx = '\0';
|
||||
|
||||
CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
|
||||
reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
|
||||
|
||||
if (reg_err == 0)
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
static char msg[80];
|
||||
|
||||
regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
|
||||
regfree ((regex_t *) CGEN_INSN_RX (insn));
|
||||
free (CGEN_INSN_RX (insn));
|
||||
(CGEN_INSN_RX (insn)) = NULL;
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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 = cd->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 *
|
||||
iq2000_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;
|
||||
int recognized_mnemonic = 0;
|
||||
|
||||
/* 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;
|
||||
recognized_mnemonic = 1;
|
||||
|
||||
#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 (! iq2000_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;
|
||||
|
||||
/* Skip this insn if str doesn't look right lexically. */
|
||||
if (CGEN_INSN_RX (insn) != NULL &&
|
||||
regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
|
||||
continue;
|
||||
|
||||
/* 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 :
|
||||
recognized_mnemonic ?
|
||||
_("unrecognized form of instruction") :
|
||||
_("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
|
||||
iq2000_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 (! iq2000_cgen_opval_supported (ke))
|
||||
continue;
|
||||
#endif
|
||||
cgen_asm_record_register (cd, ke->name, ke->value);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
2222
opcodes/iq2000-desc.c
Normal file
2222
opcodes/iq2000-desc.c
Normal file
File diff suppressed because it is too large
Load Diff
302
opcodes/iq2000-desc.h
Normal file
302
opcodes/iq2000-desc.h
Normal file
@ -0,0 +1,302 @@
|
||||
/* CPU data header for iq2000.
|
||||
|
||||
THIS FILE IS MACHINE GENERATED WITH CGEN.
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 IQ2000_CPU_H
|
||||
#define IQ2000_CPU_H
|
||||
|
||||
#define CGEN_ARCH iq2000
|
||||
|
||||
/* Given symbol S, return iq2000_cgen_<S>. */
|
||||
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
|
||||
#define CGEN_SYM(s) iq2000##_cgen_##s
|
||||
#else
|
||||
#define CGEN_SYM(s) iq2000/**/_cgen_/**/s
|
||||
#endif
|
||||
|
||||
|
||||
/* Selected cpu families. */
|
||||
#define HAVE_CPU_IQ2000BF
|
||||
#define HAVE_CPU_IQ10BF
|
||||
|
||||
#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 19
|
||||
|
||||
/* 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 8
|
||||
|
||||
/* Enums. */
|
||||
|
||||
/* Enum declaration for . */
|
||||
typedef enum gr_names {
|
||||
H_GR_R0 = 0, H_GR__0 = 0, H_GR_R1 = 1, H_GR__1 = 1
|
||||
, H_GR_R2 = 2, H_GR__2 = 2, H_GR_R3 = 3, H_GR__3 = 3
|
||||
, H_GR_R4 = 4, H_GR__4 = 4, H_GR_R5 = 5, H_GR__5 = 5
|
||||
, H_GR_R6 = 6, H_GR__6 = 6, H_GR_R7 = 7, H_GR__7 = 7
|
||||
, H_GR_R8 = 8, H_GR__8 = 8, H_GR_R9 = 9, H_GR__9 = 9
|
||||
, H_GR_R10 = 10, H_GR__10 = 10, H_GR_R11 = 11, H_GR__11 = 11
|
||||
, H_GR_R12 = 12, H_GR__12 = 12, H_GR_R13 = 13, H_GR__13 = 13
|
||||
, H_GR_R14 = 14, H_GR__14 = 14, H_GR_R15 = 15, H_GR__15 = 15
|
||||
, H_GR_R16 = 16, H_GR__16 = 16, H_GR_R17 = 17, H_GR__17 = 17
|
||||
, H_GR_R18 = 18, H_GR__18 = 18, H_GR_R19 = 19, H_GR__19 = 19
|
||||
, H_GR_R20 = 20, H_GR__20 = 20, H_GR_R21 = 21, H_GR__21 = 21
|
||||
, H_GR_R22 = 22, H_GR__22 = 22, H_GR_R23 = 23, H_GR__23 = 23
|
||||
, H_GR_R24 = 24, H_GR__24 = 24, H_GR_R25 = 25, H_GR__25 = 25
|
||||
, H_GR_R26 = 26, H_GR__26 = 26, H_GR_R27 = 27, H_GR__27 = 27
|
||||
, H_GR_R28 = 28, H_GR__28 = 28, H_GR_R29 = 29, H_GR__29 = 29
|
||||
, H_GR_R30 = 30, H_GR__30 = 30, H_GR_R31 = 31, H_GR__31 = 31
|
||||
} GR_NAMES;
|
||||
|
||||
/* Enum declaration for primary opcodes. */
|
||||
typedef enum opcodes {
|
||||
OP_SPECIAL = 0, OP_REGIMM = 1, OP_J = 2, OP_JAL = 3
|
||||
, OP_BEQ = 4, OP_BNE = 5, OP_BLEZ = 6, OP_BGTZ = 7
|
||||
, OP_ADDI = 8, OP_ADDIU = 9, OP_SLTI = 10, OP_SLTIU = 11
|
||||
, OP_ANDI = 12, OP_ORI = 13, OP_XORI = 14, OP_LUI = 15
|
||||
, OP_COP0 = 16, OP_COP1 = 17, OP_COP2 = 18, OP_COP3 = 19
|
||||
, OP_BEQL = 20, OP_BNEL = 21, OP_BLEZL = 22, OP_BGTZL = 23
|
||||
, OP_BMB0 = 24, OP_BMB1 = 25, OP_BMB2 = 26, OP_BMB3 = 27
|
||||
, OP_BBI = 28, OP_BBV = 29, OP_BBIN = 30, OP_BBVN = 31
|
||||
, OP_LB = 32, OP_LH = 33, OP_LW = 35, OP_LBU = 36
|
||||
, OP_LHU = 37, OP_RAM = 39, OP_SB = 40, OP_SH = 41
|
||||
, OP_SW = 43, OP_ANDOI = 44, OP_BMB = 45, OP_ORUI = 47
|
||||
, OP_LDW = 48, OP_SDW = 56, OP_ANDOUI = 63
|
||||
} OPCODES;
|
||||
|
||||
/* Enum declaration for iq10-only primary opcodes. */
|
||||
typedef enum q10_opcodes {
|
||||
OP10_BMB = 6, OP10_ORUI = 15, OP10_BMBL = 22, OP10_ANDOUI = 47
|
||||
, OP10_BBIL = 60, OP10_BBVL = 61, OP10_BBINL = 62, OP10_BBVNL = 63
|
||||
} Q10_OPCODES;
|
||||
|
||||
/* Enum declaration for branch sub-opcodes. */
|
||||
typedef enum regimm_functions {
|
||||
FUNC_BLTZ = 0, FUNC_BGEZ = 1, FUNC_BLTZL = 2, FUNC_BGEZL = 3
|
||||
, FUNC_BLEZ = 4, FUNC_BGTZ = 5, FUNC_BLEZL = 6, FUNC_BGTZL = 7
|
||||
, FUNC_BRI = 8, FUNC_BRV = 9, FUNC_BCTX = 12, FUNC_BLTZAL = 16
|
||||
, FUNC_BGEZAL = 17, FUNC_BLTZALL = 18, FUNC_BGEZALL = 19, FUNC_BLEZAL = 20
|
||||
, FUNC_BGTZAL = 21, FUNC_BLEZALL = 22, FUNC_BGTZALL = 23
|
||||
} REGIMM_FUNCTIONS;
|
||||
|
||||
/* Enum declaration for function sub-opcodes. */
|
||||
typedef enum functions {
|
||||
FUNC_SLL = 0, FUNC_SLMV = 1, FUNC_SRL = 2, FUNC_SRA = 3
|
||||
, FUNC_SLLV = 4, FUNC_SRMV = 5, FUNC_SRLV = 6, FUNC_SRAV = 7
|
||||
, FUNC_JR = 8, FUNC_JALR = 9, FUNC_JCR = 10, FUNC_SYSCALL = 12
|
||||
, FUNC_BREAK = 13, FUNC_SLEEP = 14, FUNC_ADD = 32, FUNC_ADDU = 33
|
||||
, FUNC_SUB = 34, FUNC_SUBU = 35, FUNC_AND = 36, FUNC_OR = 37
|
||||
, FUNC_XOR = 38, FUNC_NOR = 39, FUNC_ADO16 = 41, FUNC_SLT = 42
|
||||
, FUNC_SLTU = 43, FUNC_MRGB = 45
|
||||
} FUNCTIONS;
|
||||
|
||||
/* Enum declaration for iq10-only special function sub-opcodes. */
|
||||
typedef enum q10s_functions {
|
||||
FUNC10_YIELD = 14, FUNC10_CNT1S = 46
|
||||
} Q10S_FUNCTIONS;
|
||||
|
||||
/* Enum declaration for iq10 function sub-opcodes. */
|
||||
typedef enum cop_functions {
|
||||
FUNC10_CFC = 0, FUNC10_LOCK = 1, FUNC10_CTC = 2, FUNC10_UNLK = 3
|
||||
, FUNC10_SWRD = 4, FUNC10_SWRDL = 5, FUNC10_SWWR = 6, FUNC10_SWWRU = 7
|
||||
, FUNC10_RBA = 8, FUNC10_RBAL = 9, FUNC10_RBAR = 10, FUNC10_DWRD = 12
|
||||
, FUNC10_DWRDL = 13, FUNC10_WBA = 16, FUNC10_WBAU = 17, FUNC10_WBAC = 18
|
||||
, FUNC10_CRC32 = 20, FUNC10_CRC32B = 21, FUNC10_MCID = 32, FUNC10_DBD = 33
|
||||
, FUNC10_DBA = 34, FUNC10_DPWT = 35, FUNC10_AVAIL = 36, FUNC10_FREE = 37
|
||||
, FUNC10_CHKHDR = 38, FUNC10_TSTOD = 39, FUNC10_PKRLA = 40, FUNC10_PKRLAU = 41
|
||||
, FUNC10_PKRLAH = 42, FUNC10_PKRLAC = 43, FUNC10_CMPHDR = 44, FUNC10_CM64RS = 0
|
||||
, FUNC10_CM64RD = 1, FUNC10_CM64RI = 4, FUNC10_CM64CLR = 5, FUNC10_CM64SS = 8
|
||||
, FUNC10_CM64SD = 9, FUNC10_CM64SI = 12, FUNC10_CM64RA = 16, FUNC10_CM64RIA2 = 20
|
||||
, FUNC10_CM128RIA2 = 21, FUNC10_CM64SA = 24, FUNC10_CM64SIA2 = 28, FUNC10_CM128SIA2 = 29
|
||||
, FUNC10_CM32RS = 32, FUNC10_CM32RD = 33, FUNC10_CM32XOR = 34, FUNC10_CM32ANDN = 35
|
||||
, FUNC10_CM32RI = 36, FUNC10_CM128VSA = 38, FUNC10_CM32SS = 40, FUNC10_CM32SD = 41
|
||||
, FUNC10_CM32OR = 42, FUNC10_CM32AND = 43, FUNC10_CM32SI = 44, FUNC10_CM32RA = 48
|
||||
, FUNC10_CM32SA = 56
|
||||
} COP_FUNCTIONS;
|
||||
|
||||
/* Enum declaration for iq10 function sub-opcodes. */
|
||||
typedef enum cop_cm128_4functions {
|
||||
FUNC10_CM128RIA3 = 4, FUNC10_CM128SIA3 = 6
|
||||
} COP_CM128_4FUNCTIONS;
|
||||
|
||||
/* Enum declaration for iq10 function sub-opcodes. */
|
||||
typedef enum cop_cm128_3functions {
|
||||
FUNC10_CM128RIA4 = 6, FUNC10_CM128SIA4 = 7
|
||||
} COP_CM128_3FUNCTIONS;
|
||||
|
||||
/* Enum declaration for iq10 coprocessor sub-opcodes. */
|
||||
typedef enum cop2_functions {
|
||||
FUNC10_PKRLI = 0, FUNC10_PKRLIU = 1, FUNC10_PKRLIH = 2, FUNC10_PKRLIC = 3
|
||||
, FUNC10_RBIR = 1, FUNC10_RBI = 2, FUNC10_RBIL = 3, FUNC10_WBIC = 5
|
||||
, FUNC10_WBI = 6, FUNC10_WBIU = 7
|
||||
} COP2_FUNCTIONS;
|
||||
|
||||
/* Enum declaration for iq10 coprocessor cam sub-opcodes. */
|
||||
typedef enum cop3_cam_functions {
|
||||
FUNC10_CAM36 = 16, FUNC10_CAM72 = 17, FUNC10_CAM144 = 18, FUNC10_CAM288 = 19
|
||||
} COP3_CAM_FUNCTIONS;
|
||||
|
||||
/* Attributes. */
|
||||
|
||||
/* Enum declaration for machine type selection. */
|
||||
typedef enum mach_attr {
|
||||
MACH_BASE, MACH_IQ2000, MACH_IQ10, MACH_MAX
|
||||
} MACH_ATTR;
|
||||
|
||||
/* Enum declaration for instruction set selection. */
|
||||
typedef enum isa_attr {
|
||||
ISA_IQ2000, ISA_MAX
|
||||
} ISA_ATTR;
|
||||
|
||||
/* Number of architecture variants. */
|
||||
#define MAX_ISAS 1
|
||||
#define MAX_MACHS ((int) MACH_MAX)
|
||||
|
||||
/* Ifield support. */
|
||||
|
||||
extern const struct cgen_ifld iq2000_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 iq2000 ifield types. */
|
||||
typedef enum ifield_type {
|
||||
IQ2000_F_NIL, IQ2000_F_ANYOF, IQ2000_F_OPCODE, IQ2000_F_RS
|
||||
, IQ2000_F_RT, IQ2000_F_RD, IQ2000_F_SHAMT, IQ2000_F_CP_OP
|
||||
, IQ2000_F_CP_OP_10, IQ2000_F_CP_GRP, IQ2000_F_FUNC, IQ2000_F_IMM
|
||||
, IQ2000_F_RD_RS, IQ2000_F_RD_RT, IQ2000_F_RT_RS, IQ2000_F_JTARG
|
||||
, IQ2000_F_JTARGQ10, IQ2000_F_OFFSET, IQ2000_F_COUNT, IQ2000_F_BYTECOUNT
|
||||
, IQ2000_F_INDEX, IQ2000_F_MASK, IQ2000_F_MASKQ10, IQ2000_F_MASKL
|
||||
, IQ2000_F_EXCODE, IQ2000_F_RSRVD, IQ2000_F_10_11, IQ2000_F_24_19
|
||||
, IQ2000_F_5, IQ2000_F_10, IQ2000_F_25, IQ2000_F_CAM_Z
|
||||
, IQ2000_F_CAM_Y, IQ2000_F_CM_3FUNC, IQ2000_F_CM_4FUNC, IQ2000_F_CM_3Z
|
||||
, IQ2000_F_CM_4Z, IQ2000_F_MAX
|
||||
} IFIELD_TYPE;
|
||||
|
||||
#define MAX_IFLD ((int) IQ2000_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 iq2000 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_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 iq2000 operand types. */
|
||||
typedef enum cgen_operand_type {
|
||||
IQ2000_OPERAND_PC, IQ2000_OPERAND_RS, IQ2000_OPERAND_RT, IQ2000_OPERAND_RD
|
||||
, IQ2000_OPERAND_RD_RS, IQ2000_OPERAND_RD_RT, IQ2000_OPERAND_RT_RS, IQ2000_OPERAND_SHAMT
|
||||
, IQ2000_OPERAND_IMM, IQ2000_OPERAND_OFFSET, IQ2000_OPERAND_BASEOFF, IQ2000_OPERAND_JMPTARG
|
||||
, IQ2000_OPERAND_MASK, IQ2000_OPERAND_MASKQ10, IQ2000_OPERAND_MASKL, IQ2000_OPERAND_COUNT
|
||||
, IQ2000_OPERAND_INDEX, IQ2000_OPERAND_EXECODE, IQ2000_OPERAND_BYTECOUNT, IQ2000_OPERAND_CAM_Y
|
||||
, IQ2000_OPERAND_CAM_Z, IQ2000_OPERAND_CM_3FUNC, IQ2000_OPERAND_CM_4FUNC, IQ2000_OPERAND_CM_3Z
|
||||
, IQ2000_OPERAND_CM_4Z, IQ2000_OPERAND_BASE, IQ2000_OPERAND_MASKR, IQ2000_OPERAND_BITNUM
|
||||
, IQ2000_OPERAND_HI16, IQ2000_OPERAND_LO16, IQ2000_OPERAND_MLO16, IQ2000_OPERAND_JMPTARGQ10
|
||||
, IQ2000_OPERAND_MAX
|
||||
} CGEN_OPERAND_TYPE;
|
||||
|
||||
/* Number of operands types. */
|
||||
#define MAX_OPERANDS 32
|
||||
|
||||
/* 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_YIELD_INSN, CGEN_INSN_LOAD_DELAY
|
||||
, CGEN_INSN_EVEN_REG_NUM, CGEN_INSN_UNSUPPORTED, CGEN_INSN_USES_RD, CGEN_INSN_USES_RS
|
||||
, CGEN_INSN_USES_RT, CGEN_INSN_USES_R31, 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 iq2000_cgen_hardware_attr_table[];
|
||||
extern const CGEN_ATTR_TABLE iq2000_cgen_ifield_attr_table[];
|
||||
extern const CGEN_ATTR_TABLE iq2000_cgen_operand_attr_table[];
|
||||
extern const CGEN_ATTR_TABLE iq2000_cgen_insn_attr_table[];
|
||||
|
||||
/* Hardware decls. */
|
||||
|
||||
extern CGEN_KEYWORD iq2000_cgen_opval_gr_names;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* IQ2000_CPU_H */
|
619
opcodes/iq2000-dis.c
Normal file
619
opcodes/iq2000-dis.c
Normal file
@ -0,0 +1,619 @@
|
||||
/* 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 "iq2000-desc.h"
|
||||
#include "iq2000-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 *, unsigned));
|
||||
static int default_print_insn
|
||||
PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *));
|
||||
static int read_insn
|
||||
PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *, char *, int,
|
||||
CGEN_EXTRACT_INFO *, unsigned long *));
|
||||
|
||||
/* -- disassembler routines inserted here */
|
||||
|
||||
|
||||
void iq2000_cgen_print_operand
|
||||
PARAMS ((CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *,
|
||||
void const *, bfd_vma, int));
|
||||
|
||||
/* 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
|
||||
iq2000_cgen_print_operand (cd, opindex, xinfo, fields, attrs, pc, length)
|
||||
CGEN_CPU_DESC cd;
|
||||
int opindex;
|
||||
PTR xinfo;
|
||||
CGEN_FIELDS *fields;
|
||||
void const *attrs ATTRIBUTE_UNUSED;
|
||||
bfd_vma pc;
|
||||
int length;
|
||||
{
|
||||
disassemble_info *info = (disassemble_info *) xinfo;
|
||||
|
||||
switch (opindex)
|
||||
{
|
||||
case IQ2000_OPERAND_BASE :
|
||||
print_keyword (cd, info, & iq2000_cgen_opval_gr_names, fields->f_rs, 0);
|
||||
break;
|
||||
case IQ2000_OPERAND_BASEOFF :
|
||||
print_address (cd, info, fields->f_imm, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_BITNUM :
|
||||
print_normal (cd, info, fields->f_rt, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_BYTECOUNT :
|
||||
print_normal (cd, info, fields->f_bytecount, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_CAM_Y :
|
||||
print_normal (cd, info, fields->f_cam_y, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_CAM_Z :
|
||||
print_normal (cd, info, fields->f_cam_z, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_CM_3FUNC :
|
||||
print_normal (cd, info, fields->f_cm_3func, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_CM_3Z :
|
||||
print_normal (cd, info, fields->f_cm_3z, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_CM_4FUNC :
|
||||
print_normal (cd, info, fields->f_cm_4func, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_CM_4Z :
|
||||
print_normal (cd, info, fields->f_cm_4z, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_COUNT :
|
||||
print_normal (cd, info, fields->f_count, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_EXECODE :
|
||||
print_normal (cd, info, fields->f_excode, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_HI16 :
|
||||
print_normal (cd, info, fields->f_imm, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_IMM :
|
||||
print_normal (cd, info, fields->f_imm, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_INDEX :
|
||||
print_normal (cd, info, fields->f_index, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_JMPTARG :
|
||||
print_address (cd, info, fields->f_jtarg, 0|(1<<CGEN_OPERAND_ABS_ADDR), pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_JMPTARGQ10 :
|
||||
print_address (cd, info, fields->f_jtargq10, 0|(1<<CGEN_OPERAND_ABS_ADDR), pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_LO16 :
|
||||
print_normal (cd, info, fields->f_imm, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_MASK :
|
||||
print_normal (cd, info, fields->f_mask, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_MASKL :
|
||||
print_normal (cd, info, fields->f_maskl, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_MASKQ10 :
|
||||
print_normal (cd, info, fields->f_maskq10, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_MASKR :
|
||||
print_normal (cd, info, fields->f_rs, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_MLO16 :
|
||||
print_normal (cd, info, fields->f_imm, 0, pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_OFFSET :
|
||||
print_address (cd, info, fields->f_offset, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
|
||||
break;
|
||||
case IQ2000_OPERAND_RD :
|
||||
print_keyword (cd, info, & iq2000_cgen_opval_gr_names, fields->f_rd, 0);
|
||||
break;
|
||||
case IQ2000_OPERAND_RD_RS :
|
||||
print_keyword (cd, info, & iq2000_cgen_opval_gr_names, fields->f_rd_rs, 0|(1<<CGEN_OPERAND_VIRTUAL));
|
||||
break;
|
||||
case IQ2000_OPERAND_RD_RT :
|
||||
print_keyword (cd, info, & iq2000_cgen_opval_gr_names, fields->f_rd_rt, 0|(1<<CGEN_OPERAND_VIRTUAL));
|
||||
break;
|
||||
case IQ2000_OPERAND_RS :
|
||||
print_keyword (cd, info, & iq2000_cgen_opval_gr_names, fields->f_rs, 0);
|
||||
break;
|
||||
case IQ2000_OPERAND_RT :
|
||||
print_keyword (cd, info, & iq2000_cgen_opval_gr_names, fields->f_rt, 0);
|
||||
break;
|
||||
case IQ2000_OPERAND_RT_RS :
|
||||
print_keyword (cd, info, & iq2000_cgen_opval_gr_names, fields->f_rt_rs, 0|(1<<CGEN_OPERAND_VIRTUAL));
|
||||
break;
|
||||
case IQ2000_OPERAND_SHAMT :
|
||||
print_normal (cd, info, fields->f_shamt, 0, pc, length);
|
||||
break;
|
||||
|
||||
default :
|
||||
/* xgettext:c-format */
|
||||
fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
|
||||
opindex);
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
cgen_print_fn * const iq2000_cgen_print_handlers[] =
|
||||
{
|
||||
print_insn_normal,
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
iq2000_cgen_init_dis (cd)
|
||||
CGEN_CPU_DESC cd;
|
||||
{
|
||||
iq2000_cgen_init_opcode_table (cd);
|
||||
iq2000_cgen_init_ibld_table (cd);
|
||||
cd->print_handlers = & iq2000_cgen_print_handlers[0];
|
||||
cd->print_operand = iq2000_cgen_print_operand;
|
||||
}
|
||||
|
||||
|
||||
/* Default print handler. */
|
||||
|
||||
static void
|
||||
print_normal (cd, dis_info, value, attrs, pc, length)
|
||||
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
|
||||
PTR dis_info;
|
||||
long value;
|
||||
unsigned int attrs;
|
||||
bfd_vma pc ATTRIBUTE_UNUSED;
|
||||
int length ATTRIBUTE_UNUSED;
|
||||
{
|
||||
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)
|
||||
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
|
||||
PTR dis_info;
|
||||
bfd_vma value;
|
||||
unsigned int attrs;
|
||||
bfd_vma pc ATTRIBUTE_UNUSED;
|
||||
int length ATTRIBUTE_UNUSED;
|
||||
{
|
||||
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. */
|
||||
iq2000_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 ATTRIBUTE_UNUSED;
|
||||
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;
|
||||
unsigned int buflen;
|
||||
{
|
||||
CGEN_INSN_INT insn_value;
|
||||
const CGEN_INSN_LIST *insn_list;
|
||||
CGEN_EXTRACT_INFO ex_info;
|
||||
int basesize;
|
||||
|
||||
/* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
|
||||
basesize = cd->base_insn_bitsize < buflen * 8 ?
|
||||
cd->base_insn_bitsize : buflen * 8;
|
||||
insn_value = cgen_get_insn_value (cd, buf, basesize);
|
||||
|
||||
|
||||
/* Fill in ex_info fields like read_insn would. Don't actually call
|
||||
read_insn, since the incoming buffer is already read (and possibly
|
||||
modified a la m32r). */
|
||||
ex_info.valid = (1 << buflen) - 1;
|
||||
ex_info.dis_info = info;
|
||||
ex_info.insn_bytes = buf;
|
||||
|
||||
/* 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;
|
||||
unsigned long insn_value_cropped;
|
||||
|
||||
#ifdef CGEN_VALIDATE_INSN_SUPPORTED
|
||||
/* Not needed as insn shouldn't be in hash lists if not supported. */
|
||||
/* Supported by this cpu? */
|
||||
if (! iq2000_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. */
|
||||
|
||||
/* Base size may exceed this instruction's size. Extract the
|
||||
relevant part from the buffer. */
|
||||
if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
|
||||
(unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
|
||||
insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
|
||||
info->endian == BFD_ENDIAN_BIG);
|
||||
else
|
||||
insn_value_cropped = insn_value;
|
||||
|
||||
if ((insn_value_cropped & 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 (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) &&
|
||||
(unsigned) (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_cropped, &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 buflen;
|
||||
int status;
|
||||
|
||||
/* Attempt to read the base part of the insn. */
|
||||
buflen = cd->base_insn_bitsize / 8;
|
||||
status = (*info->read_memory_func) (pc, buf, buflen, info);
|
||||
|
||||
/* Try again with the minimum part, if min < base. */
|
||||
if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
|
||||
{
|
||||
buflen = cd->min_insn_bitsize / 8;
|
||||
status = (*info->read_memory_func) (pc, buf, buflen, info);
|
||||
}
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
(*info->memory_error_func) (status, pc, info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return print_insn (cd, pc, info, buf, buflen);
|
||||
}
|
||||
|
||||
/* Main entry point.
|
||||
Print one instruction from PC on INFO->STREAM.
|
||||
Return the size of the instruction (in bytes). */
|
||||
|
||||
typedef struct cpu_desc_list {
|
||||
struct cpu_desc_list *next;
|
||||
int isa;
|
||||
int mach;
|
||||
int endian;
|
||||
CGEN_CPU_DESC cd;
|
||||
} cpu_desc_list;
|
||||
|
||||
int
|
||||
print_insn_iq2000 (pc, info)
|
||||
bfd_vma pc;
|
||||
disassemble_info *info;
|
||||
{
|
||||
static cpu_desc_list *cd_list = 0;
|
||||
cpu_desc_list *cl = 0;
|
||||
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_iq2000
|
||||
#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 = info->insn_sets;
|
||||
#endif
|
||||
|
||||
/* If we've switched cpu's, try to find a handle we've used before */
|
||||
if (cd
|
||||
&& (isa != prev_isa
|
||||
|| mach != prev_mach
|
||||
|| endian != prev_endian))
|
||||
{
|
||||
cd = 0;
|
||||
for (cl = cd_list; cl; cl = cl->next)
|
||||
{
|
||||
if (cl->isa == isa &&
|
||||
cl->mach == mach &&
|
||||
cl->endian == endian)
|
||||
{
|
||||
cd = cl->cd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 = iq2000_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 ();
|
||||
|
||||
/* save this away for future reference */
|
||||
cl = xmalloc (sizeof (struct cpu_desc_list));
|
||||
cl->cd = cd;
|
||||
cl->isa = isa;
|
||||
cl->mach = mach;
|
||||
cl->endian = endian;
|
||||
cl->next = cd_list;
|
||||
cd_list = cl;
|
||||
|
||||
iq2000_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;
|
||||
}
|
1394
opcodes/iq2000-ibld.c
Normal file
1394
opcodes/iq2000-ibld.c
Normal file
File diff suppressed because it is too large
Load Diff
3482
opcodes/iq2000-opc.c
Normal file
3482
opcodes/iq2000-opc.c
Normal file
File diff suppressed because it is too large
Load Diff
181
opcodes/iq2000-opc.h
Normal file
181
opcodes/iq2000-opc.h
Normal file
@ -0,0 +1,181 @@
|
||||
/* Instruction opcode header for iq2000.
|
||||
|
||||
THIS FILE IS MACHINE GENERATED WITH CGEN.
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 IQ2000_OPC_H
|
||||
#define IQ2000_OPC_H
|
||||
|
||||
/* -- opc.h */
|
||||
|
||||
/* Allows reason codes to be output when assembler errors occur. */
|
||||
#define CGEN_VERBOSE_ASSEMBLER_ERRORS
|
||||
|
||||
/* Override disassembly hashing - there are variable bits in the top
|
||||
byte of these instructions. */
|
||||
#define CGEN_DIS_HASH_SIZE 8
|
||||
#define CGEN_DIS_HASH(buf,value) (((* (unsigned char*) (buf)) >> 6) % CGEN_DIS_HASH_SIZE)
|
||||
|
||||
/* following activates check beyond hashing since some iq2000 and iq10
|
||||
instructions have same mnemonics but different functionality. */
|
||||
#define CGEN_VALIDATE_INSN_SUPPORTED
|
||||
|
||||
extern int iq2000_cgen_insn_supported (CGEN_CPU_DESC cd, CGEN_INSN *insn);
|
||||
|
||||
/* -- asm.c */
|
||||
/* Enum declaration for iq2000 instruction types. */
|
||||
typedef enum cgen_insn_type {
|
||||
IQ2000_INSN_INVALID, IQ2000_INSN_ADD2, IQ2000_INSN_ADD, IQ2000_INSN_ADDI2
|
||||
, IQ2000_INSN_ADDI, IQ2000_INSN_ADDIU2, IQ2000_INSN_ADDIU, IQ2000_INSN_ADDU2
|
||||
, IQ2000_INSN_ADDU, IQ2000_INSN_ADO162, IQ2000_INSN_ADO16, IQ2000_INSN_AND2
|
||||
, IQ2000_INSN_AND, IQ2000_INSN_ANDI2, IQ2000_INSN_ANDI, IQ2000_INSN_ANDOI2
|
||||
, IQ2000_INSN_ANDOI, IQ2000_INSN_NOR2, IQ2000_INSN_NOR, IQ2000_INSN_OR2
|
||||
, IQ2000_INSN_OR, IQ2000_INSN_ORI2, IQ2000_INSN_ORI, IQ2000_INSN_RAM
|
||||
, IQ2000_INSN_SLL, IQ2000_INSN_SLLV2, IQ2000_INSN_SLLV, IQ2000_INSN_SLMV2
|
||||
, IQ2000_INSN_SLMV, IQ2000_INSN_SLT2, IQ2000_INSN_SLT, IQ2000_INSN_SLTI2
|
||||
, IQ2000_INSN_SLTI, IQ2000_INSN_SLTIU2, IQ2000_INSN_SLTIU, IQ2000_INSN_SLTU2
|
||||
, IQ2000_INSN_SLTU, IQ2000_INSN_SRA2, IQ2000_INSN_SRA, IQ2000_INSN_SRAV2
|
||||
, IQ2000_INSN_SRAV, IQ2000_INSN_SRL, IQ2000_INSN_SRLV2, IQ2000_INSN_SRLV
|
||||
, IQ2000_INSN_SRMV2, IQ2000_INSN_SRMV, IQ2000_INSN_SUB2, IQ2000_INSN_SUB
|
||||
, IQ2000_INSN_SUBU2, IQ2000_INSN_SUBU, IQ2000_INSN_XOR2, IQ2000_INSN_XOR
|
||||
, IQ2000_INSN_XORI2, IQ2000_INSN_XORI, IQ2000_INSN_BBI, IQ2000_INSN_BBIN
|
||||
, IQ2000_INSN_BBV, IQ2000_INSN_BBVN, IQ2000_INSN_BEQ, IQ2000_INSN_BEQL
|
||||
, IQ2000_INSN_BGEZ, IQ2000_INSN_BGEZAL, IQ2000_INSN_BGEZALL, IQ2000_INSN_BGEZL
|
||||
, IQ2000_INSN_BLTZ, IQ2000_INSN_BLTZL, IQ2000_INSN_BLTZAL, IQ2000_INSN_BLTZALL
|
||||
, IQ2000_INSN_BMB0, IQ2000_INSN_BMB1, IQ2000_INSN_BMB2, IQ2000_INSN_BMB3
|
||||
, IQ2000_INSN_BNE, IQ2000_INSN_BNEL, IQ2000_INSN_JALR, IQ2000_INSN_JR
|
||||
, IQ2000_INSN_LB, IQ2000_INSN_LBU, IQ2000_INSN_LH, IQ2000_INSN_LHU
|
||||
, IQ2000_INSN_LUI, IQ2000_INSN_LW, IQ2000_INSN_SB, IQ2000_INSN_SH
|
||||
, IQ2000_INSN_SW, IQ2000_INSN_BREAK, IQ2000_INSN_SYSCALL, IQ2000_INSN_ANDOUI
|
||||
, IQ2000_INSN_ANDOUI2, IQ2000_INSN_ORUI2, IQ2000_INSN_ORUI, IQ2000_INSN_BGTZ
|
||||
, IQ2000_INSN_BGTZL, IQ2000_INSN_BLEZ, IQ2000_INSN_BLEZL, IQ2000_INSN_MRGB
|
||||
, IQ2000_INSN_MRGB2, IQ2000_INSN_BCTXT, IQ2000_INSN_BC0F, IQ2000_INSN_BC0FL
|
||||
, IQ2000_INSN_BC3F, IQ2000_INSN_BC3FL, IQ2000_INSN_BC0T, IQ2000_INSN_BC0TL
|
||||
, IQ2000_INSN_BC3T, IQ2000_INSN_BC3TL, IQ2000_INSN_CFC0, IQ2000_INSN_CFC1
|
||||
, IQ2000_INSN_CFC2, IQ2000_INSN_CFC3, IQ2000_INSN_CHKHDR, IQ2000_INSN_CTC0
|
||||
, IQ2000_INSN_CTC1, IQ2000_INSN_CTC2, IQ2000_INSN_CTC3, IQ2000_INSN_JCR
|
||||
, IQ2000_INSN_LUC32, IQ2000_INSN_LUC32L, IQ2000_INSN_LUC64, IQ2000_INSN_LUC64L
|
||||
, IQ2000_INSN_LUK, IQ2000_INSN_LULCK, IQ2000_INSN_LUM32, IQ2000_INSN_LUM32L
|
||||
, IQ2000_INSN_LUM64, IQ2000_INSN_LUM64L, IQ2000_INSN_LUR, IQ2000_INSN_LURL
|
||||
, IQ2000_INSN_LUULCK, IQ2000_INSN_MFC0, IQ2000_INSN_MFC1, IQ2000_INSN_MFC2
|
||||
, IQ2000_INSN_MFC3, IQ2000_INSN_MTC0, IQ2000_INSN_MTC1, IQ2000_INSN_MTC2
|
||||
, IQ2000_INSN_MTC3, IQ2000_INSN_PKRL, IQ2000_INSN_PKRLR1, IQ2000_INSN_PKRLR30
|
||||
, IQ2000_INSN_RB, IQ2000_INSN_RBR1, IQ2000_INSN_RBR30, IQ2000_INSN_RFE
|
||||
, IQ2000_INSN_RX, IQ2000_INSN_RXR1, IQ2000_INSN_RXR30, IQ2000_INSN_SLEEP
|
||||
, IQ2000_INSN_SRRD, IQ2000_INSN_SRRDL, IQ2000_INSN_SRULCK, IQ2000_INSN_SRWR
|
||||
, IQ2000_INSN_SRWRU, IQ2000_INSN_TRAPQFL, IQ2000_INSN_TRAPQNE, IQ2000_INSN_TRAPREL
|
||||
, IQ2000_INSN_WB, IQ2000_INSN_WBU, IQ2000_INSN_WBR1, IQ2000_INSN_WBR1U
|
||||
, IQ2000_INSN_WBR30, IQ2000_INSN_WBR30U, IQ2000_INSN_WX, IQ2000_INSN_WXU
|
||||
, IQ2000_INSN_WXR1, IQ2000_INSN_WXR1U, IQ2000_INSN_WXR30, IQ2000_INSN_WXR30U
|
||||
, IQ2000_INSN_LDW, IQ2000_INSN_SDW, IQ2000_INSN_J, IQ2000_INSN_JAL
|
||||
, IQ2000_INSN_BMB, IQ2000_INSN_ANDOUI_Q10, IQ2000_INSN_ANDOUI2_Q10, IQ2000_INSN_ORUI_Q10
|
||||
, IQ2000_INSN_ORUI2_Q10, IQ2000_INSN_MRGBQ10, IQ2000_INSN_MRGBQ102, IQ2000_INSN_JQ10
|
||||
, IQ2000_INSN_JALQ10, IQ2000_INSN_JALQ10_2, IQ2000_INSN_BBIL, IQ2000_INSN_BBINL
|
||||
, IQ2000_INSN_BBVL, IQ2000_INSN_BBVNL, IQ2000_INSN_BGTZAL, IQ2000_INSN_BGTZALL
|
||||
, IQ2000_INSN_BLEZAL, IQ2000_INSN_BLEZALL, IQ2000_INSN_BGTZ_Q10, IQ2000_INSN_BGTZL_Q10
|
||||
, IQ2000_INSN_BLEZ_Q10, IQ2000_INSN_BLEZL_Q10, IQ2000_INSN_BMB_Q10, IQ2000_INSN_BMBL
|
||||
, IQ2000_INSN_BRI, IQ2000_INSN_BRV, IQ2000_INSN_BCTX, IQ2000_INSN_YIELD
|
||||
, IQ2000_INSN_CRC32, IQ2000_INSN_CRC32B, IQ2000_INSN_CNT1S, IQ2000_INSN_AVAIL
|
||||
, IQ2000_INSN_FREE, IQ2000_INSN_TSTOD, IQ2000_INSN_CMPHDR, IQ2000_INSN_MCID
|
||||
, IQ2000_INSN_DBA, IQ2000_INSN_DBD, IQ2000_INSN_DPWT, IQ2000_INSN_CHKHDRQ10
|
||||
, IQ2000_INSN_RBA, IQ2000_INSN_RBAL, IQ2000_INSN_RBAR, IQ2000_INSN_WBA
|
||||
, IQ2000_INSN_WBAU, IQ2000_INSN_WBAC, IQ2000_INSN_RBI, IQ2000_INSN_RBIL
|
||||
, IQ2000_INSN_RBIR, IQ2000_INSN_WBI, IQ2000_INSN_WBIC, IQ2000_INSN_WBIU
|
||||
, IQ2000_INSN_PKRLI, IQ2000_INSN_PKRLIH, IQ2000_INSN_PKRLIU, IQ2000_INSN_PKRLIC
|
||||
, IQ2000_INSN_PKRLA, IQ2000_INSN_PKRLAU, IQ2000_INSN_PKRLAH, IQ2000_INSN_PKRLAC
|
||||
, IQ2000_INSN_LOCK, IQ2000_INSN_UNLK, IQ2000_INSN_SWRD, IQ2000_INSN_SWRDL
|
||||
, IQ2000_INSN_SWWR, IQ2000_INSN_SWWRU, IQ2000_INSN_DWRD, IQ2000_INSN_DWRDL
|
||||
, IQ2000_INSN_CAM36, IQ2000_INSN_CAM72, IQ2000_INSN_CAM144, IQ2000_INSN_CAM288
|
||||
, IQ2000_INSN_CM32AND, IQ2000_INSN_CM32ANDN, IQ2000_INSN_CM32OR, IQ2000_INSN_CM32RA
|
||||
, IQ2000_INSN_CM32RD, IQ2000_INSN_CM32RI, IQ2000_INSN_CM32RS, IQ2000_INSN_CM32SA
|
||||
, IQ2000_INSN_CM32SD, IQ2000_INSN_CM32SI, IQ2000_INSN_CM32SS, IQ2000_INSN_CM32XOR
|
||||
, IQ2000_INSN_CM64CLR, IQ2000_INSN_CM64RA, IQ2000_INSN_CM64RD, IQ2000_INSN_CM64RI
|
||||
, IQ2000_INSN_CM64RIA2, IQ2000_INSN_CM64RS, IQ2000_INSN_CM64SA, IQ2000_INSN_CM64SD
|
||||
, IQ2000_INSN_CM64SI, IQ2000_INSN_CM64SIA2, IQ2000_INSN_CM64SS, IQ2000_INSN_CM128RIA2
|
||||
, IQ2000_INSN_CM128RIA3, IQ2000_INSN_CM128RIA4, IQ2000_INSN_CM128SIA2, IQ2000_INSN_CM128SIA3
|
||||
, IQ2000_INSN_CM128SIA4, IQ2000_INSN_CM128VSA, IQ2000_INSN_CFC, IQ2000_INSN_CTC
|
||||
} CGEN_INSN_TYPE;
|
||||
|
||||
/* Index of `invalid' insn place holder. */
|
||||
#define CGEN_INSN_INVALID IQ2000_INSN_INVALID
|
||||
|
||||
/* Total number of insns in table. */
|
||||
#define MAX_INSNS ((int) IQ2000_INSN_CTC + 1)
|
||||
|
||||
/* This struct records data prior to insertion or after extraction. */
|
||||
struct cgen_fields
|
||||
{
|
||||
int length;
|
||||
long f_nil;
|
||||
long f_anyof;
|
||||
long f_opcode;
|
||||
long f_rs;
|
||||
long f_rt;
|
||||
long f_rd;
|
||||
long f_shamt;
|
||||
long f_cp_op;
|
||||
long f_cp_op_10;
|
||||
long f_cp_grp;
|
||||
long f_func;
|
||||
long f_imm;
|
||||
long f_rd_rs;
|
||||
long f_rd_rt;
|
||||
long f_rt_rs;
|
||||
long f_jtarg;
|
||||
long f_jtargq10;
|
||||
long f_offset;
|
||||
long f_count;
|
||||
long f_bytecount;
|
||||
long f_index;
|
||||
long f_mask;
|
||||
long f_maskq10;
|
||||
long f_maskl;
|
||||
long f_excode;
|
||||
long f_rsrvd;
|
||||
long f_10_11;
|
||||
long f_24_19;
|
||||
long f_5;
|
||||
long f_10;
|
||||
long f_25;
|
||||
long f_cam_z;
|
||||
long f_cam_y;
|
||||
long f_cm_3func;
|
||||
long f_cm_4func;
|
||||
long f_cm_3z;
|
||||
long f_cm_4z;
|
||||
};
|
||||
|
||||
#define CGEN_INIT_PARSE(od) \
|
||||
{\
|
||||
}
|
||||
#define CGEN_INIT_INSERT(od) \
|
||||
{\
|
||||
}
|
||||
#define CGEN_INIT_EXTRACT(od) \
|
||||
{\
|
||||
}
|
||||
#define CGEN_INIT_PRINT(od) \
|
||||
{\
|
||||
}
|
||||
|
||||
|
||||
#endif /* IQ2000_OPC_H */
|
Loading…
Reference in New Issue
Block a user