mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-25 21:19:54 +00:00
Wed Nov 4 18:46:47 1998 Dave Brolley <brolley@cygnus.com>
* configure.in): Added case for bfd_fr30_arch. * Makefile.am (CFILES): Added fr30-asm.c, fr30-dis.c, fr30-opc.c. (ALL_MACHINES): Added fr30-asm.lo, fr30-dis.lo, fr30-opc.lo. (CLEANFILES): Added stamp-fr30. (FR30_DEPS): Added. * fr30-asm.c: New file. * fr30-dis.c: New file. * fr30-opc.c: New file. * fr30-opc.h: New file.
This commit is contained in:
parent
63d138d980
commit
a86481d3e9
@ -1,3 +1,15 @@
|
||||
Wed Nov 4 18:46:47 1998 Dave Brolley <brolley@cygnus.com>
|
||||
|
||||
* configure.in): Added case for bfd_fr30_arch.
|
||||
* Makefile.am (CFILES): Added fr30-asm.c, fr30-dis.c, fr30-opc.c.
|
||||
(ALL_MACHINES): Added fr30-asm.lo, fr30-dis.lo, fr30-opc.lo.
|
||||
(CLEANFILES): Added stamp-fr30.
|
||||
(FR30_DEPS): Added.
|
||||
* fr30-asm.c: New file.
|
||||
* fr30-dis.c: New file.
|
||||
* fr30-opc.c: New file.
|
||||
* fr30-opc.h: New file.
|
||||
|
||||
Mon Nov 2 15:05:33 1998 Geoffrey Noer <noer@cygnus.com>
|
||||
|
||||
* configure.in: detect cygwin* instead of cygwin32*
|
||||
|
@ -33,8 +33,13 @@ CFILES = \
|
||||
cgen-opc.c \
|
||||
d10v-dis.c \
|
||||
d10v-opc.c \
|
||||
d30v-dis.c \
|
||||
d30v-opc.c \
|
||||
dis-buf.c \
|
||||
disassemble.c \
|
||||
fr30-asm.c \
|
||||
fr30-dis.c \
|
||||
fr30-opc.c \
|
||||
h8300-dis.c \
|
||||
h8500-dis.c \
|
||||
hppa-dis.c \
|
||||
@ -77,10 +82,11 @@ ALL_MACHINES = \
|
||||
cgen-opc.lo \
|
||||
d10v-dis.lo \
|
||||
d10v-opc.lo \
|
||||
$(start-sanitize-d30v) \
|
||||
d30v-dis.lo \
|
||||
d30v-opc.lo \
|
||||
$(end-sanitize-d30v) \
|
||||
fr30-asm.lo \
|
||||
fr30-dis.lo \
|
||||
fr30-opc.lo \
|
||||
h8300-dis.lo \
|
||||
h8500-dis.lo \
|
||||
hppa-dis.lo \
|
||||
@ -160,7 +166,7 @@ config.status: $(srcdir)/configure $(srcdir)/../bfd/configure.in
|
||||
|
||||
CLEANFILES = libopcodes.a stamp-lib dep.sed .dep .dep1
|
||||
# start-sanitize-cygnus
|
||||
CLEANFILES = libopcodes.a stamp-lib dep.sed .dep .dep1 stamp-m32r
|
||||
CLEANFILES = libopcodes.a stamp-lib dep.sed .dep .dep1 stamp-m32r stamp-fr30
|
||||
# end-sanitize-cygnus
|
||||
|
||||
# start-sanitize-cygnus
|
||||
@ -168,42 +174,46 @@ CLEANFILES = libopcodes.a stamp-lib dep.sed .dep .dep1 stamp-m32r
|
||||
# Sanitization must be split between assignments and rules because
|
||||
# automake splits them that way.
|
||||
|
||||
SCHEME = @SCHEME@
|
||||
SCHEMEFLAGS = -s
|
||||
CGENDIR = $(srcdir)/../cgen
|
||||
CGENDIR = @cgendir@
|
||||
CGEN = @cgen@
|
||||
CGENFLAGS = -v
|
||||
|
||||
CGENFILES = $(CGENDIR)/object.scm $(CGENDIR)/utils.scm \
|
||||
CGENFILES = $(CGENDIR)/cos.scm $(CGENDIR)/utils.scm \
|
||||
$(CGENDIR)/attr.scm $(CGENDIR)/enum.scm $(CGENDIR)/types.scm \
|
||||
$(CGENDIR)/utils-cgen.scm $(CGENDIR)/cpu.scm \
|
||||
$(CGENDIR)/mode.scm $(CGENDIR)/mach.scm \
|
||||
$(CGENDIR)/model.scm $(CGENDIR)/hardware.scm \
|
||||
$(CGENDIR)/ifield.scm $(CGENDIR)/iformat.scm \
|
||||
$(CGENDIR)/operand.scm $(CGENDIR)/insn.scm $(CGENDIR)/minsn.scm \
|
||||
$(CGENDIR)/opcodes.scm $(CGENDIR)/cdl-c.scm \
|
||||
$(CGENDIR)/opcodes.scm $(CGENDIR)/rtl.scm \
|
||||
$(CGENDIR)/cgen-opc.scm cgen-opc.in cgen-asm.in cgen-dis.in
|
||||
# The CGEN_MAINT conditional is put here so it end up in Makefile.in
|
||||
# The CGEN_MAINT conditional is put here so it ends up in Makefile.in
|
||||
# properly sanitized.
|
||||
if CGEN_MAINT
|
||||
M32R_DEPS = stamp-m32r
|
||||
FR30_DEPS = stamp-fr30
|
||||
else
|
||||
M32R_DEPS =
|
||||
FR30_DEPS =
|
||||
endif
|
||||
# The end marker is written this way to pass through automake unscathed.
|
||||
ENDSAN = end-sanitize-cygnus
|
||||
|
||||
# start-sanitize-cygnus
|
||||
cgen:
|
||||
$(SHELL) $(srcdir)/cgen.sh opcodes $(srcdir) $(CGENDIR) $(CGENFLAGS) $(SCHEME) $(SCHEMEFLAGS) $(arch)
|
||||
touch stamp-${arch}
|
||||
|
||||
.PHONY: cgen
|
||||
run-cgen:
|
||||
$(SHELL) $(srcdir)/cgen.sh opcodes $(srcdir) $(CGEN) $(CGENDIR) $(CGENFLAGS) $(arch) $(prefix)
|
||||
touch stamp-${prefix}
|
||||
.PHONY: run-cgen
|
||||
|
||||
# For now, require developers to configure with --enable-cgen-maint.
|
||||
m32r-opc.h m32r-opc.c m32r-asm.c m32r-dis.c: $(M32R_DEPS)
|
||||
@true
|
||||
stamp-m32r: $(CGENFILES) $(CGENDIR)/m32r.cpu $(CGENDIR)/m32r.opc
|
||||
$(MAKE) cgen arch=m32r prefix=m32r
|
||||
$(MAKE) run-cgen arch=m32r prefix=m32r
|
||||
fr30-opc.h fr30-opc.c fr30-asm.c fr30-dis.c: $(FR30_DEPS)
|
||||
@true
|
||||
stamp-fr30: $(CGENFILES) $(CGENDIR)/fr30.cpu $(CGENDIR)/fr30.opc
|
||||
$(MAKE) run-cgen arch=fr30 prefix=fr30
|
||||
# end-sanitize-cygnus
|
||||
|
||||
# start-sanitize-tic80
|
||||
@ -273,7 +283,8 @@ alpha-opc.lo: alpha-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/alpha.h \
|
||||
$(BFD_H) opintl.h
|
||||
arm-dis.lo: arm-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
|
||||
$(INCDIR)/ansidecl.h arm-opc.h $(INCDIR)/coff/internal.h \
|
||||
$(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h opintl.h
|
||||
$(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h opintl.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h
|
||||
cgen-asm.lo: cgen-asm.c sysdep.h config.h $(INCDIR)/libiberty.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/cgen.h \
|
||||
opintl.h
|
||||
@ -284,6 +295,9 @@ cgen-opc.lo: cgen-opc.c sysdep.h config.h $(INCDIR)/libiberty.h \
|
||||
d10v-dis.lo: d10v-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d10v.h \
|
||||
$(INCDIR)/dis-asm.h $(BFD_H)
|
||||
d10v-opc.lo: d10v-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d10v.h
|
||||
d30v-dis.lo: d30v-dis.c $(INCDIR)/opcode/d30v.h $(INCDIR)/dis-asm.h \
|
||||
$(BFD_H) $(INCDIR)/ansidecl.h opintl.h
|
||||
d30v-opc.lo: d30v-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d30v.h
|
||||
dis-buf.lo: dis-buf.c sysdep.h config.h $(INCDIR)/dis-asm.h \
|
||||
$(BFD_H) opintl.h
|
||||
disassemble.lo: disassemble.c $(INCDIR)/ansidecl.h \
|
||||
@ -307,6 +321,15 @@ m32r-dis.lo: m32r-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
|
||||
m32r-opc.lo: m32r-opc.c sysdep.h config.h $(INCDIR)/libiberty.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h m32r-opc.h $(INCDIR)/opcode/cgen.h \
|
||||
opintl.h
|
||||
fr30-asm.lo: fr30-asm.c sysdep.h config.h $(BFD_H) \
|
||||
$(INCDIR)/symcat.h fr30-opc.h $(INCDIR)/opcode/cgen.h \
|
||||
opintl.h
|
||||
fr30-dis.lo: fr30-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h fr30-opc.h $(INCDIR)/opcode/cgen.h \
|
||||
opintl.h
|
||||
fr30-opc.lo: fr30-opc.c sysdep.h config.h $(INCDIR)/libiberty.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h fr30-opc.h $(INCDIR)/opcode/cgen.h \
|
||||
opintl.h
|
||||
m68k-dis.lo: m68k-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
|
||||
$(INCDIR)/ansidecl.h $(INCDIR)/floatformat.h opintl.h \
|
||||
$(INCDIR)/opcode/m68k.h
|
||||
@ -316,9 +339,8 @@ m88k-dis.lo: m88k-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
|
||||
mips-dis.lo: mips-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
|
||||
$(BFD_H) $(INCDIR)/opcode/mips.h opintl.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
|
||||
$(INCDIR)/bfdlink.h $(INCDIR)/elf/mips.h
|
||||
mips-opc.lo: mips-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h \
|
||||
vu0.h
|
||||
$(INCDIR)/bfdlink.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h
|
||||
mips-opc.lo: mips-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h
|
||||
mips16-opc.lo: mips16-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h
|
||||
m10200-dis.lo: m10200-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10200.h \
|
||||
$(INCDIR)/dis-asm.h $(BFD_H) opintl.h
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Makefile.in generated automatically by automake 1.3 from Makefile.am
|
||||
# Makefile.in generated automatically by automake 1.3b from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
@ -32,7 +32,7 @@ mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
DISTDIR =
|
||||
DESTDIR =
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
@ -64,18 +64,47 @@ host_triplet = @host@
|
||||
target_alias = @target_alias@
|
||||
target_triplet = @target@
|
||||
AR = @AR@
|
||||
AS = @AS@
|
||||
BFD_MACHINES = @BFD_MACHINES@
|
||||
CATALOGS = @CATALOGS@
|
||||
CATOBJEXT = @CATOBJEXT@
|
||||
CC = @CC@
|
||||
CC_FOR_BUILD = @CC_FOR_BUILD@
|
||||
DATADIRNAME = @DATADIRNAME@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
EXEEXT = @EXEEXT@
|
||||
EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
|
||||
GMOFILES = @GMOFILES@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GT_NO = @GT_NO@
|
||||
GT_YES = @GT_YES@
|
||||
HDEFINES = @HDEFINES@
|
||||
INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
|
||||
INSTOBJEXT = @INSTOBJEXT@
|
||||
INTLDEPS = @INTLDEPS@
|
||||
INTLLIBS = @INTLLIBS@
|
||||
INTLOBJS = @INTLOBJS@
|
||||
LD = @LD@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN_S = @LN_S@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKINSTALLDIRS = @MKINSTALLDIRS@
|
||||
MSGFMT = @MSGFMT@
|
||||
NM = @NM@
|
||||
PACKAGE = @PACKAGE@
|
||||
POFILES = @POFILES@
|
||||
POSUB = @POSUB@
|
||||
RANLIB = @RANLIB@
|
||||
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
|
||||
USE_NLS = @USE_NLS@
|
||||
VERSION = @VERSION@
|
||||
WIN32LDFLAGS = @WIN32LDFLAGS@
|
||||
WIN32LIBADD = @WIN32LIBADD@
|
||||
archdefs = @archdefs@
|
||||
cgen = @cgen@
|
||||
cgendir = @cgendir@
|
||||
l = @l@
|
||||
|
||||
AUTOMAKE_OPTIONS = cygnus
|
||||
|
||||
@ -110,8 +139,13 @@ CFILES = \
|
||||
cgen-opc.c \
|
||||
d10v-dis.c \
|
||||
d10v-opc.c \
|
||||
d30v-dis.c \
|
||||
d30v-opc.c \
|
||||
dis-buf.c \
|
||||
disassemble.c \
|
||||
fr30-asm.c \
|
||||
fr30-dis.c \
|
||||
fr30-opc.c \
|
||||
h8300-dis.c \
|
||||
h8500-dis.c \
|
||||
hppa-dis.c \
|
||||
@ -154,10 +188,11 @@ ALL_MACHINES = \
|
||||
cgen-opc.lo \
|
||||
d10v-dis.lo \
|
||||
d10v-opc.lo \
|
||||
$(start-sanitize-d30v) \
|
||||
d30v-dis.lo \
|
||||
d30v-opc.lo \
|
||||
$(end-sanitize-d30v) \
|
||||
fr30-asm.lo \
|
||||
fr30-dis.lo \
|
||||
fr30-opc.lo \
|
||||
h8300-dis.lo \
|
||||
h8500-dis.lo \
|
||||
hppa-dis.lo \
|
||||
@ -217,7 +252,7 @@ POTFILES = $(HFILES) $(CFILES)
|
||||
|
||||
CLEANFILES = libopcodes.a stamp-lib dep.sed .dep .dep1
|
||||
# start-sanitize-cygnus
|
||||
CLEANFILES = libopcodes.a stamp-lib dep.sed .dep .dep1 stamp-m32r
|
||||
CLEANFILES = libopcodes.a stamp-lib dep.sed .dep .dep1 stamp-m32r stamp-fr30
|
||||
# end-sanitize-cygnus
|
||||
|
||||
# start-sanitize-cygnus
|
||||
@ -236,12 +271,14 @@ CGENFILES = $(CGENDIR)/cos.scm $(CGENDIR)/utils.scm \
|
||||
$(CGENDIR)/model.scm $(CGENDIR)/hardware.scm \
|
||||
$(CGENDIR)/ifield.scm $(CGENDIR)/iformat.scm \
|
||||
$(CGENDIR)/operand.scm $(CGENDIR)/insn.scm $(CGENDIR)/minsn.scm \
|
||||
$(CGENDIR)/opcodes.scm $(CGENDIR)/cdl-c.scm \
|
||||
$(CGENDIR)/opcodes.scm $(CGENDIR)/rtl.scm \
|
||||
$(CGENDIR)/cgen-opc.scm cgen-opc.in cgen-asm.in cgen-dis.in
|
||||
# The CGEN_MAINT conditional is put here so it end up in Makefile.in
|
||||
# The CGEN_MAINT conditional is put here so it ends up in Makefile.in
|
||||
# properly sanitized.
|
||||
@CGEN_MAINT_TRUE@M32R_DEPS = stamp-m32r
|
||||
@CGEN_MAINT_TRUE@FR30_DEPS = stamp-fr30
|
||||
@CGEN_MAINT_FALSE@M32R_DEPS =
|
||||
@CGEN_MAINT_FALSE@FR30_DEPS =
|
||||
# The end marker is written this way to pass through automake unscathed.
|
||||
ENDSAN = end-sanitize-cygnus
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
@ -262,16 +299,13 @@ LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
|
||||
libopcodes_la_OBJECTS = dis-buf.lo disassemble.lo
|
||||
CFLAGS = @CFLAGS@
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
||||
LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
|
||||
DIST_COMMON = ChangeLog Makefile.am Makefile.in acconfig.h acinclude.m4 \
|
||||
aclocal.m4 config.in configure configure.in stamp-h.in
|
||||
|
||||
|
||||
PACKAGE = @PACKAGE@
|
||||
VERSION = @VERSION@
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
@ -407,7 +441,7 @@ check-recursive installcheck-recursive info-recursive dvi-recursive:
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
(cd $$subdir && $(MAKE) $$target) \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$target) \
|
||||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||
done && test -z "$$fail"
|
||||
|
||||
@ -420,12 +454,12 @@ maintainer-clean-recursive:
|
||||
for subdir in $$rev; do \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
(cd $$subdir && $(MAKE) $$target) \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$target) \
|
||||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||
done && test -z "$$fail"
|
||||
tags-recursive:
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
(cd $$subdir && $(MAKE) tags); \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
|
||||
done
|
||||
|
||||
tags: TAGS
|
||||
@ -470,12 +504,12 @@ distcheck: dist
|
||||
dc_install_base=`cd $(distdir)/=inst && pwd`; \
|
||||
cd $(distdir)/=build \
|
||||
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
|
||||
&& $(MAKE) \
|
||||
&& $(MAKE) dvi \
|
||||
&& $(MAKE) check \
|
||||
&& $(MAKE) install \
|
||||
&& $(MAKE) installcheck \
|
||||
&& $(MAKE) dist
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dist
|
||||
-rm -rf $(distdir)
|
||||
@echo "========================"; \
|
||||
echo "$(distdir).tar.gz is ready for distribution"; \
|
||||
@ -503,17 +537,17 @@ distdir: $(DISTFILES)
|
||||
|| mkdir $(distdir)/$$subdir \
|
||||
|| exit 1; \
|
||||
chmod 777 $(distdir)/$$subdir; \
|
||||
(cd $$subdir && $(MAKE) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
|
||||
|| exit 1; \
|
||||
done
|
||||
info: info-recursive
|
||||
dvi: dvi-recursive
|
||||
check:
|
||||
$(MAKE) check-recursive
|
||||
$(MAKE) $(AM_MAKEFLAGS) check-recursive
|
||||
installcheck: installcheck-recursive
|
||||
install-info: install-info-recursive
|
||||
all-recursive-am: config.h
|
||||
$(MAKE) all-recursive
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
||||
|
||||
all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) config.h
|
||||
|
||||
@ -533,25 +567,21 @@ install: install-recursive install-exec-am
|
||||
uninstall: uninstall-recursive uninstall-am
|
||||
|
||||
install-strip:
|
||||
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
|
||||
installdirs: installdirs-recursive
|
||||
$(mkinstalldirs) $(DATADIR)$(libdir)
|
||||
$(mkinstalldirs) $(DESTDIR)$(libdir)
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(DISTCLEANFILES)
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
mostlyclean-am: mostlyclean-hdr mostlyclean-noinstLIBRARIES \
|
||||
mostlyclean-compile mostlyclean-libtool \
|
||||
mostlyclean-libLTLIBRARIES mostlyclean-tags \
|
||||
@ -626,17 +656,20 @@ config.status: $(srcdir)/configure $(srcdir)/../bfd/configure.in
|
||||
$(SHELL) ./config.status --recheck
|
||||
|
||||
# start-sanitize-cygnus
|
||||
cgen:
|
||||
run-cgen:
|
||||
$(SHELL) $(srcdir)/cgen.sh opcodes $(srcdir) $(CGEN) $(CGENDIR) $(CGENFLAGS) $(arch) $(prefix)
|
||||
touch stamp-${prefix}
|
||||
|
||||
.PHONY: cgen
|
||||
.PHONY: run-cgen
|
||||
|
||||
# For now, require developers to configure with --enable-cgen-maint.
|
||||
m32r-opc.h m32r-opc.c m32r-asm.c m32r-dis.c: $(M32R_DEPS)
|
||||
@true
|
||||
stamp-m32r: $(CGENFILES) $(CGENDIR)/m32r.cpu $(CGENDIR)/m32r.opc
|
||||
$(MAKE) cgen arch=m32r prefix=m32r
|
||||
$(MAKE) run-cgen arch=m32r prefix=m32r
|
||||
fr30-opc.h fr30-opc.c fr30-asm.c fr30-dis.c: $(FR30_DEPS)
|
||||
@true
|
||||
stamp-fr30: $(CGENFILES) $(CGENDIR)/fr30.cpu $(CGENDIR)/fr30.opc
|
||||
$(MAKE) run-cgen arch=fr30 prefix=fr30
|
||||
# end-sanitize-cygnus
|
||||
|
||||
# start-sanitize-tic80
|
||||
@ -706,7 +739,8 @@ alpha-opc.lo: alpha-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/alpha.h \
|
||||
$(BFD_H) opintl.h
|
||||
arm-dis.lo: arm-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
|
||||
$(INCDIR)/ansidecl.h arm-opc.h $(INCDIR)/coff/internal.h \
|
||||
$(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h opintl.h
|
||||
$(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h opintl.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h
|
||||
cgen-asm.lo: cgen-asm.c sysdep.h config.h $(INCDIR)/libiberty.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/cgen.h \
|
||||
opintl.h
|
||||
@ -717,6 +751,9 @@ cgen-opc.lo: cgen-opc.c sysdep.h config.h $(INCDIR)/libiberty.h \
|
||||
d10v-dis.lo: d10v-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d10v.h \
|
||||
$(INCDIR)/dis-asm.h $(BFD_H)
|
||||
d10v-opc.lo: d10v-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d10v.h
|
||||
d30v-dis.lo: d30v-dis.c $(INCDIR)/opcode/d30v.h $(INCDIR)/dis-asm.h \
|
||||
$(BFD_H) $(INCDIR)/ansidecl.h opintl.h
|
||||
d30v-opc.lo: d30v-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d30v.h
|
||||
dis-buf.lo: dis-buf.c sysdep.h config.h $(INCDIR)/dis-asm.h \
|
||||
$(BFD_H) opintl.h
|
||||
disassemble.lo: disassemble.c $(INCDIR)/ansidecl.h \
|
||||
@ -740,6 +777,15 @@ m32r-dis.lo: m32r-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
|
||||
m32r-opc.lo: m32r-opc.c sysdep.h config.h $(INCDIR)/libiberty.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h m32r-opc.h $(INCDIR)/opcode/cgen.h \
|
||||
opintl.h
|
||||
fr30-asm.lo: fr30-asm.c sysdep.h config.h $(BFD_H) \
|
||||
$(INCDIR)/symcat.h fr30-opc.h $(INCDIR)/opcode/cgen.h \
|
||||
opintl.h
|
||||
fr30-dis.lo: fr30-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h fr30-opc.h $(INCDIR)/opcode/cgen.h \
|
||||
opintl.h
|
||||
fr30-opc.lo: fr30-opc.c sysdep.h config.h $(INCDIR)/libiberty.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h fr30-opc.h $(INCDIR)/opcode/cgen.h \
|
||||
opintl.h
|
||||
m68k-dis.lo: m68k-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
|
||||
$(INCDIR)/ansidecl.h $(INCDIR)/floatformat.h opintl.h \
|
||||
$(INCDIR)/opcode/m68k.h
|
||||
@ -749,9 +795,8 @@ m88k-dis.lo: m88k-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
|
||||
mips-dis.lo: mips-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
|
||||
$(BFD_H) $(INCDIR)/opcode/mips.h opintl.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
|
||||
$(INCDIR)/bfdlink.h $(INCDIR)/elf/mips.h
|
||||
mips-opc.lo: mips-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h \
|
||||
vu0.h
|
||||
$(INCDIR)/bfdlink.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h
|
||||
mips-opc.lo: mips-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h
|
||||
mips16-opc.lo: mips16-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h
|
||||
m10200-dis.lo: m10200-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10200.h \
|
||||
$(INCDIR)/dis-asm.h $(BFD_H) opintl.h
|
||||
|
805
opcodes/configure
vendored
805
opcodes/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -163,6 +163,7 @@ if test x${all_targets} = xfalse ; then
|
||||
bfd_convex_arch) ;;
|
||||
bfd_d10v_arch) ta="$ta d10v-dis.lo d10v-opc.lo" ;;
|
||||
bfd_d30v_arch) ta="$ta d30v-dis.lo d30v-opc.lo" ;;
|
||||
bfd_fr30_arch) ta="$ta $cgen_files fr30-opc.lo fr30-asm.lo fr30-dis.lo" ;;
|
||||
bfd_h8300_arch) ta="$ta h8300-dis.lo" ;;
|
||||
bfd_h8500_arch) ta="$ta h8500-dis.lo" ;;
|
||||
bfd_hppa_arch) ta="$ta hppa-dis.lo" ;;
|
||||
|
756
opcodes/fr30-asm.c
Normal file
756
opcodes/fr30-asm.c
Normal file
@ -0,0 +1,756 @@
|
||||
/* Assembler interface for targets using CGEN. -*- C -*-
|
||||
CGEN: Cpu tools GENerator
|
||||
|
||||
THIS FILE IS USED TO GENERATE fr30-asm.c.
|
||||
|
||||
Copyright (C) 1996, 1997, 1998 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. */
|
||||
|
||||
#include "sysdep.h"
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include "ansidecl.h"
|
||||
#include "bfd.h"
|
||||
#include "symcat.h"
|
||||
#include "fr30-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))
|
||||
|
||||
#undef INLINE
|
||||
#ifdef __GNUC__
|
||||
#define INLINE __inline__
|
||||
#else
|
||||
#define INLINE
|
||||
#endif
|
||||
|
||||
static const char * insert_normal
|
||||
PARAMS ((CGEN_OPCODE_DESC, long, unsigned int, int, int, int,
|
||||
CGEN_INSN_BYTES_PTR));
|
||||
static const char * parse_insn_normal
|
||||
PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *,
|
||||
const char **, CGEN_FIELDS *));
|
||||
static const char * insert_insn_normal
|
||||
PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *,
|
||||
CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
|
||||
|
||||
/* -- assembler routines inserted here */
|
||||
|
||||
/* 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 *
|
||||
fr30_cgen_parse_operand (od, opindex, strp, fields)
|
||||
CGEN_OPCODE_DESC od;
|
||||
int opindex;
|
||||
const char ** strp;
|
||||
CGEN_FIELDS * fields;
|
||||
{
|
||||
const char * errmsg;
|
||||
|
||||
switch (opindex)
|
||||
{
|
||||
case FR30_OPERAND_RI :
|
||||
errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_gr, & fields->f_Ri);
|
||||
break;
|
||||
case FR30_OPERAND_RJ :
|
||||
errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_gr, & fields->f_Rj);
|
||||
break;
|
||||
|
||||
default :
|
||||
/* xgettext:c-format */
|
||||
fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
|
||||
abort ();
|
||||
}
|
||||
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
/* 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 *
|
||||
fr30_cgen_insert_operand (od, opindex, fields, buffer, pc)
|
||||
CGEN_OPCODE_DESC od;
|
||||
int opindex;
|
||||
CGEN_FIELDS * fields;
|
||||
CGEN_INSN_BYTES_PTR buffer;
|
||||
bfd_vma pc;
|
||||
{
|
||||
const char * errmsg;
|
||||
|
||||
switch (opindex)
|
||||
{
|
||||
case FR30_OPERAND_RI :
|
||||
errmsg = insert_normal (od, fields->f_Ri, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case FR30_OPERAND_RJ :
|
||||
errmsg = insert_normal (od, fields->f_Rj, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
|
||||
default :
|
||||
/* xgettext:c-format */
|
||||
fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
|
||||
opindex);
|
||||
abort ();
|
||||
}
|
||||
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
cgen_parse_fn * const fr30_cgen_parse_handlers[] =
|
||||
{
|
||||
0, /* default */
|
||||
parse_insn_normal,
|
||||
};
|
||||
|
||||
cgen_insert_fn * const fr30_cgen_insert_handlers[] =
|
||||
{
|
||||
0, /* default */
|
||||
insert_insn_normal,
|
||||
};
|
||||
|
||||
void
|
||||
fr30_cgen_init_asm (od)
|
||||
CGEN_OPCODE_DESC od;
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#if ! CGEN_INT_INSN_P
|
||||
|
||||
/* Subroutine of insert_normal. */
|
||||
|
||||
static INLINE void
|
||||
insert_1 (od, value, start, length, word_length, bufp)
|
||||
CGEN_OPCODE_DESC od;
|
||||
unsigned long value;
|
||||
int start,length,word_length;
|
||||
unsigned char *bufp;
|
||||
{
|
||||
unsigned long x,mask;
|
||||
int shift;
|
||||
int big_p = CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG;
|
||||
|
||||
switch (word_length)
|
||||
{
|
||||
case 8:
|
||||
x = *bufp;
|
||||
break;
|
||||
case 16:
|
||||
if (big_p)
|
||||
x = bfd_getb16 (bufp);
|
||||
else
|
||||
x = bfd_getl16 (bufp);
|
||||
break;
|
||||
case 24:
|
||||
/* ??? This may need reworking as these cases don't necessarily
|
||||
want the first byte and the last two bytes handled like this. */
|
||||
if (big_p)
|
||||
x = (bfd_getb8 (bufp) << 16) | bfd_getb16 (bufp + 1);
|
||||
else
|
||||
x = bfd_getl16 (bufp) | (bfd_getb8 (bufp + 2) << 16);
|
||||
break;
|
||||
case 32:
|
||||
if (big_p)
|
||||
x = bfd_getb32 (bufp);
|
||||
else
|
||||
x = bfd_getl32 (bufp);
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Written this way to avoid undefined behaviour. */
|
||||
mask = (((1L << (length - 1)) - 1) << 1) | 1;
|
||||
if (CGEN_INSN_LSB0_P)
|
||||
shift = start;
|
||||
else
|
||||
shift = (word_length - (start + length));
|
||||
x = (x & ~(mask << shift)) | ((value & mask) << shift);
|
||||
|
||||
switch (word_length)
|
||||
{
|
||||
case 8:
|
||||
*bufp = x;
|
||||
break;
|
||||
case 16:
|
||||
if (big_p)
|
||||
bfd_putb16 (x, bufp);
|
||||
else
|
||||
bfd_putl16 (x, bufp);
|
||||
break;
|
||||
case 24:
|
||||
/* ??? This may need reworking as these cases don't necessarily
|
||||
want the first byte and the last two bytes handled like this. */
|
||||
if (big_p)
|
||||
{
|
||||
bfd_putb8 (x >> 16, bufp);
|
||||
bfd_putb16 (x, bufp + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_putl16 (x, bufp);
|
||||
bfd_putb8 (x >> 16, bufp + 2);
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
if (big_p)
|
||||
bfd_putb32 (x, bufp);
|
||||
else
|
||||
bfd_putl32 (x, bufp);
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ! CGEN_INT_INSN_P */
|
||||
|
||||
/* Default insertion routine.
|
||||
|
||||
ATTRS is a mask of the boolean attributes.
|
||||
START is the starting bit number, architecture origin.
|
||||
LENGTH is the length of VALUE in bits.
|
||||
TOTAL_LENGTH is the total length of the insn.
|
||||
|
||||
The result is an error message or NULL if success. */
|
||||
|
||||
/* ??? May need to know word length in order to properly place values as
|
||||
an insn may be made of multiple words and the current bit number handling
|
||||
may be insufficient. Word length is an architectural attribute and thus
|
||||
methinks the way to go [if needed] is to fetch this value from OD or
|
||||
define a macro in <arch>-opc.h rather than adding an extra argument -
|
||||
after all that's how endianness is handled. */
|
||||
/* ??? This duplicates functionality with bfd's howto table and
|
||||
bfd_install_relocation. */
|
||||
/* ??? For architectures where insns can be representable as ints,
|
||||
store insn in `field' struct and add registers, etc. while parsing? */
|
||||
/* ??? This doesn't handle bfd_vma's. Create another function when
|
||||
necessary. */
|
||||
|
||||
static const char *
|
||||
insert_normal (od, value, attrs, start, length, total_length, buffer)
|
||||
CGEN_OPCODE_DESC od;
|
||||
long value;
|
||||
unsigned int attrs;
|
||||
int start;
|
||||
int length;
|
||||
int 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;
|
||||
|
||||
/* Ensure VALUE will fit. */
|
||||
if ((attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED)) != 0)
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
|
||||
if (total_length > 32)
|
||||
abort ();
|
||||
{
|
||||
int shift;
|
||||
|
||||
if (CGEN_INSN_LSB0_P)
|
||||
shift = start;
|
||||
else
|
||||
shift = total_length - (start + length);
|
||||
*buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* FIXME: unfinished and untested */
|
||||
|
||||
/* ??? To be defined in <arch>-opc.h as necessary. */
|
||||
#ifndef CGEN_WORD_ENDIAN
|
||||
#define CGEN_WORD_ENDIAN(od) CGEN_OPCODE_ENDIAN (od)
|
||||
#endif
|
||||
#ifndef CGEN_INSN_WORD_ENDIAN
|
||||
#define CGEN_INSN_WORD_ENDIAN(od) CGEN_WORD_ENDIAN (od)
|
||||
#endif
|
||||
|
||||
/* The hard case is probably too slow for the normal cases.
|
||||
It's certainly more difficult to understand than the normal case.
|
||||
Thus this is split into two. Keep it that way. The hard case is defined
|
||||
to be when a field straddles a (loosely defined) word boundary
|
||||
(??? which may require target specific help to determine). */
|
||||
|
||||
#if 0 /*wip*/
|
||||
|
||||
#define HARD_CASE_P 0 /* FIXME:wip */
|
||||
|
||||
if (HARD_CASE_P)
|
||||
{
|
||||
unsigned char *bufp = (unsigned char *) buffer;
|
||||
int insn_length_left = total_length;
|
||||
|
||||
if (CGEN_INSN_LSB0_P)
|
||||
{
|
||||
int word_offset = (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG
|
||||
? ...
|
||||
: start / CGEN_BASE_INSN_BITSIZE);
|
||||
bufp += word_offset * (CGEN_BASE_INSN_BITSIZE / 8);
|
||||
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
|
||||
else
|
||||
start -= word_offset * CGEN_BASE_INSN_BITSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
int word_offset = (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG
|
||||
? start / CGEN_BASE_INSN_BITSIZE
|
||||
: ...);
|
||||
bufp += word_offset * (CGEN_BASE_INSN_BITSIZE / 8);
|
||||
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
|
||||
start -= word_offset * CGEN_BASE_INSN_BITSIZE;
|
||||
else
|
||||
}
|
||||
|
||||
/* Loop so we handle a field straddling an insn word boundary
|
||||
(remember, "insn word boundary" is loosely defined here). */
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
int this_pass_length = length;
|
||||
int this_pass_start = start;
|
||||
int this_pass_word_length = min (insn_length_left,
|
||||
(CGEN_BASE_INSN_BITSIZE == 8
|
||||
? 32
|
||||
: CGEN_BASE_INSN_BITSIZE));
|
||||
|
||||
insert_1 (od, value, attrs,
|
||||
this_pass_start, this_pass_length, this_pass_word_length,
|
||||
bufp);
|
||||
|
||||
length -= this_pass_length;
|
||||
insn_length_left -= this_pass_word_length;
|
||||
if (???)
|
||||
{
|
||||
value >>= ???;
|
||||
start += ???;
|
||||
}
|
||||
else
|
||||
{
|
||||
value >>= ???;
|
||||
start += ???;
|
||||
}
|
||||
bufp += this_pass_word_length / 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* 0 */
|
||||
{
|
||||
unsigned char *bufp = (unsigned char *) buffer;
|
||||
|
||||
if (length > 32)
|
||||
abort ();
|
||||
|
||||
/* Adjust start,total_length,bufp to point to the pseudo-word that holds
|
||||
the value. For example in a 48 bit insn where the value to insert
|
||||
(say an immediate value) is the last 16 bits then word_length here
|
||||
would be 16. To handle a 24 bit insn with an 18 bit immediate,
|
||||
insert_1 handles 24 bits (using a combination of bfd_get8,16). */
|
||||
|
||||
if (total_length > 32)
|
||||
{
|
||||
int needed_width = start % 8 + length;
|
||||
int fetch_length = (needed_width <= 8 ? 8
|
||||
: needed_width <= 16 ? 16
|
||||
: 32);
|
||||
|
||||
if (CGEN_INSN_LSB0_P)
|
||||
{
|
||||
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
|
||||
{
|
||||
abort (); /* wip */
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset = start & ~7;
|
||||
|
||||
bufp += offset / 8;
|
||||
start -= offset;
|
||||
total_length -= offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
|
||||
{
|
||||
int offset = start & ~7;
|
||||
|
||||
bufp += offset / 8;
|
||||
start -= offset;
|
||||
total_length -= offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
abort (); /* wip */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
insert_1 (od, value, start, length, total_length, bufp);
|
||||
}
|
||||
|
||||
#endif /* ! CGEN_INT_INSN_P */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 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 (od, insn, strp, fields)
|
||||
CGEN_OPCODE_DESC od;
|
||||
const CGEN_INSN * insn;
|
||||
const char ** strp;
|
||||
CGEN_FIELDS * fields;
|
||||
{
|
||||
const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
|
||||
const char * str = *strp;
|
||||
const char * errmsg;
|
||||
const char * p;
|
||||
const unsigned char * 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 || (* str && !isspace (* str)))
|
||||
return _("unrecognized instruction");
|
||||
|
||||
CGEN_INIT_PARSE (od);
|
||||
cgen_init_parse_operand (od);
|
||||
#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))
|
||||
{
|
||||
if (*str == CGEN_SYNTAX_CHAR (* syn))
|
||||
{
|
||||
#ifdef CGEN_MNEMONIC_OPERANDS
|
||||
if (* syn == ' ')
|
||||
past_opcode_p = 1;
|
||||
#endif
|
||||
++ syn;
|
||||
++ str;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Syntax char didn't match. Can't be this insn. */
|
||||
/* FIXME: would like to return something like
|
||||
"expected char `c'" */
|
||||
return _("syntax error");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We have an operand of some sort. */
|
||||
errmsg = fr30_cgen_parse_operand (od, 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");
|
||||
}
|
||||
|
||||
/* Default insn builder (insert handler).
|
||||
The instruction is recorded in CGEN_INT_INSN_P byte order
|
||||
(meaning that if CGEN_INT_INSN_P BUFFER 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 (od, insn, fields, buffer, pc)
|
||||
CGEN_OPCODE_DESC od;
|
||||
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 unsigned char * syn;
|
||||
|
||||
CGEN_INIT_INSERT (od);
|
||||
value = CGEN_INSN_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
|
||||
|
||||
*buffer = value;
|
||||
|
||||
#else
|
||||
|
||||
cgen_insn_put_value (od, buffer, min (CGEN_BASE_INSN_BITSIZE,
|
||||
CGEN_FIELDS_BITSIZE (fields)),
|
||||
value);
|
||||
|
||||
#endif /* ! CGEN_INT_INSN_P */
|
||||
|
||||
/* ??? Rather than scanning the syntax string again, we could store
|
||||
in `fields' a null terminated list of the fields that are present. */
|
||||
|
||||
for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
|
||||
{
|
||||
const char *errmsg;
|
||||
|
||||
if (CGEN_SYNTAX_CHAR_P (* syn))
|
||||
continue;
|
||||
|
||||
errmsg = fr30_cgen_insert_operand (od, CGEN_SYNTAX_FIELD (*syn),
|
||||
fields, buffer, pc);
|
||||
if (errmsg)
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
const CGEN_INSN *
|
||||
fr30_cgen_assemble_insn (od, str, fields, buf, errmsg)
|
||||
CGEN_OPCODE_DESC od;
|
||||
const char * str;
|
||||
CGEN_FIELDS * fields;
|
||||
CGEN_INSN_BYTES_PTR buf;
|
||||
char ** errmsg;
|
||||
{
|
||||
const char * start;
|
||||
CGEN_INSN_LIST * ilist;
|
||||
|
||||
/* 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 (od, 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;
|
||||
|
||||
#if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
|
||||
/* Is this insn supported by the selected cpu? */
|
||||
if (! fr30_cgen_insn_supported (od, 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 (insn, CGEN_INSN_RELAX) != 0)
|
||||
continue;
|
||||
|
||||
str = start;
|
||||
|
||||
/* Record a default length for the insn. This will get set to the
|
||||
correct value while parsing. */
|
||||
/* FIXME: wip */
|
||||
CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
|
||||
|
||||
if (! CGEN_PARSE_FN (insn) (od, insn, & str, fields))
|
||||
{
|
||||
/* ??? 0 is passed for `pc' */
|
||||
if (CGEN_INSERT_FN (insn) (od, insn, fields, buf, (bfd_vma) 0) != NULL)
|
||||
continue;
|
||||
/* It is up to the caller to actually output the insn and any
|
||||
queued relocs. */
|
||||
return insn;
|
||||
}
|
||||
|
||||
/* Try the next entry. */
|
||||
}
|
||||
|
||||
/* FIXME: We can return a better error message than this.
|
||||
Need to track why it failed and pick the right one. */
|
||||
{
|
||||
static char errbuf[100];
|
||||
if (strlen (start) > 50)
|
||||
/* xgettext:c-format */
|
||||
sprintf (errbuf, _("bad instruction `%.50s...'"), start);
|
||||
else
|
||||
/* xgettext:c-format */
|
||||
sprintf (errbuf, _("bad instruction `%.50s'"), start);
|
||||
|
||||
*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
|
||||
fr30_cgen_asm_hash_keywords (od, opvals)
|
||||
CGEN_OPCODE_DESC od;
|
||||
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 (! fr30_cgen_opval_supported (ke))
|
||||
continue;
|
||||
#endif
|
||||
cgen_asm_record_register (od, ke->name, ke->value);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
663
opcodes/fr30-dis.c
Normal file
663
opcodes/fr30-dis.c
Normal file
@ -0,0 +1,663 @@
|
||||
/* Disassembler interface for targets using CGEN. -*- C -*-
|
||||
CGEN: Cpu tools GENerator
|
||||
|
||||
THIS FILE IS USED TO GENERATE fr30-dis.c.
|
||||
|
||||
Copyright (C) 1996, 1997, 1998 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. */
|
||||
|
||||
#include "sysdep.h"
|
||||
#include <stdio.h>
|
||||
#include "ansidecl.h"
|
||||
#include "dis-asm.h"
|
||||
#include "bfd.h"
|
||||
#include "symcat.h"
|
||||
#include "fr30-opc.h"
|
||||
#include "opintl.h"
|
||||
|
||||
#undef INLINE
|
||||
#ifdef __GNUC__
|
||||
#define INLINE __inline__
|
||||
#else
|
||||
#define INLINE
|
||||
#endif
|
||||
|
||||
/* Default text to print if an instruction isn't recognized. */
|
||||
#define UNKNOWN_INSN_MSG _("*unknown*")
|
||||
|
||||
static int extract_normal
|
||||
PARAMS ((CGEN_OPCODE_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_BYTES,
|
||||
unsigned int, int, int, int, long *));
|
||||
static void print_normal
|
||||
PARAMS ((CGEN_OPCODE_DESC, PTR, long, unsigned int, bfd_vma, int));
|
||||
static void print_address
|
||||
PARAMS ((CGEN_OPCODE_DESC, PTR, bfd_vma, unsigned int, bfd_vma, int));
|
||||
static void print_keyword
|
||||
PARAMS ((CGEN_OPCODE_DESC, PTR, CGEN_KEYWORD *, long, unsigned int));
|
||||
static int extract_insn_normal
|
||||
PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
|
||||
unsigned long, CGEN_FIELDS *, bfd_vma));
|
||||
static void print_insn_normal
|
||||
PARAMS ((CGEN_OPCODE_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *,
|
||||
bfd_vma, int));
|
||||
static int print_insn PARAMS ((CGEN_OPCODE_DESC, bfd_vma,
|
||||
disassemble_info *, char *, int));
|
||||
static int default_print_insn
|
||||
PARAMS ((CGEN_OPCODE_DESC, bfd_vma, disassemble_info *));
|
||||
|
||||
/* -- disassembler routines inserted here */
|
||||
|
||||
/* Main entry point for operand extraction.
|
||||
|
||||
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
|
||||
fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
|
||||
CGEN_OPCODE_DESC od;
|
||||
int opindex;
|
||||
CGEN_EXTRACT_INFO *ex_info;
|
||||
CGEN_INSN_BYTES insn_value;
|
||||
CGEN_FIELDS * fields;
|
||||
bfd_vma pc;
|
||||
{
|
||||
int length;
|
||||
|
||||
switch (opindex)
|
||||
{
|
||||
case FR30_OPERAND_RI :
|
||||
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_Ri);
|
||||
break;
|
||||
case FR30_OPERAND_RJ :
|
||||
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_Rj);
|
||||
break;
|
||||
|
||||
default :
|
||||
/* xgettext:c-format */
|
||||
fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
|
||||
opindex);
|
||||
abort ();
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/* Main entry point for printing operands.
|
||||
|
||||
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
|
||||
fr30_cgen_print_operand (od, opindex, info, fields, attrs, pc, length)
|
||||
CGEN_OPCODE_DESC od;
|
||||
int opindex;
|
||||
disassemble_info * info;
|
||||
CGEN_FIELDS * fields;
|
||||
void const * attrs;
|
||||
bfd_vma pc;
|
||||
int length;
|
||||
{
|
||||
switch (opindex)
|
||||
{
|
||||
case FR30_OPERAND_RI :
|
||||
print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Ri, 0|(1<<CGEN_OPERAND_UNSIGNED));
|
||||
break;
|
||||
case FR30_OPERAND_RJ :
|
||||
print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Rj, 0|(1<<CGEN_OPERAND_UNSIGNED));
|
||||
break;
|
||||
|
||||
default :
|
||||
/* xgettext:c-format */
|
||||
fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
|
||||
opindex);
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
cgen_extract_fn * const fr30_cgen_extract_handlers[] =
|
||||
{
|
||||
0, /* default */
|
||||
extract_insn_normal,
|
||||
};
|
||||
|
||||
cgen_print_fn * const fr30_cgen_print_handlers[] =
|
||||
{
|
||||
0, /* default */
|
||||
print_insn_normal,
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
fr30_cgen_init_dis (od)
|
||||
CGEN_OPCODE_DESC od;
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#if ! CGEN_INT_INSN_P
|
||||
|
||||
/* Subroutine of extract_normal. */
|
||||
|
||||
static INLINE long
|
||||
extract_1 (od, ex_info, start, length, word_length, bufp)
|
||||
CGEN_OPCODE_DESC od;
|
||||
CGEN_EXTRACT_INFO *info;
|
||||
int start,length,word_length;
|
||||
unsigned char *bufp;
|
||||
{
|
||||
unsigned long x,mask;
|
||||
int shift;
|
||||
int big_p = CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG;
|
||||
|
||||
/* FIXME: Need to use ex_info to ensure bytes have been fetched. */
|
||||
|
||||
switch (word_length)
|
||||
{
|
||||
case 8:
|
||||
x = *bufp;
|
||||
break;
|
||||
case 16:
|
||||
if (big_p)
|
||||
x = bfd_getb16 (bufp);
|
||||
else
|
||||
x = bfd_getl16 (bufp);
|
||||
break;
|
||||
case 24:
|
||||
/* ??? This may need reworking as these cases don't necessarily
|
||||
want the first byte and the last two bytes handled like this. */
|
||||
if (big_p)
|
||||
x = (bfd_getb8 (bufp) << 16) | bfd_getb16 (bufp + 1);
|
||||
else
|
||||
x = bfd_getl16 (bufp) | (bfd_getb8 (bufp + 2) << 16);
|
||||
break;
|
||||
case 32:
|
||||
if (big_p)
|
||||
x = bfd_getb32 (bufp);
|
||||
else
|
||||
x = bfd_getl32 (bufp);
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Written this way to avoid undefined behaviour. */
|
||||
mask = (((1L << (length - 1)) - 1) << 1) | 1;
|
||||
if (CGEN_INSN_LSB0_P)
|
||||
shift = start;
|
||||
else
|
||||
shift = (word_length - (start + length));
|
||||
return (x >> shift) & mask;
|
||||
}
|
||||
|
||||
#endif /* ! CGEN_INT_INSN_P */
|
||||
|
||||
/* Default extraction routine.
|
||||
|
||||
ATTRS is a mask of the boolean attributes. We only need `unsigned',
|
||||
but for generality we take a bitmask of all of them. */
|
||||
|
||||
/* ??? This doesn't handle bfd_vma's. Create another function when
|
||||
necessary. */
|
||||
|
||||
static int
|
||||
extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, valuep)
|
||||
CGEN_OPCODE_DESC od;
|
||||
CGEN_EXTRACT_INFO *ex_info;
|
||||
CGEN_INSN_BYTES insn_value;
|
||||
unsigned int attrs;
|
||||
int start, length, total_length;
|
||||
long *valuep;
|
||||
{
|
||||
unsigned long value;
|
||||
|
||||
/* 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 CGEN_INT_INSN_P
|
||||
|
||||
{
|
||||
/* Written this way to avoid undefined behaviour. */
|
||||
unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
|
||||
|
||||
if (CGEN_INSN_LSB0_P)
|
||||
value = insn_value >> start;
|
||||
else
|
||||
value = insn_value >> (total_length - (start + length));
|
||||
value &= mask;
|
||||
/* sign extend? */
|
||||
if (! (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED))
|
||||
&& (value & (1L << (length - 1))))
|
||||
value |= ~mask;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* The hard case is probably too slow for the normal cases.
|
||||
It's certainly more difficult to understand than the normal case.
|
||||
Thus this is split into two. Keep it that way. The hard case is defined
|
||||
to be when a field straddles a (loosely defined) word boundary
|
||||
(??? which may require target specific help to determine). */
|
||||
|
||||
#if 0 /*wip*/
|
||||
|
||||
#define HARD_CASE_P 0 /* FIXME:wip */
|
||||
|
||||
if (HARD_CASE_P)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
unsigned char *bufp = (unsigned char *) insn_value;
|
||||
|
||||
if (length > 32)
|
||||
abort ();
|
||||
|
||||
/* Adjust start,total_length,bufp to point to the pseudo-word that holds
|
||||
the value. For example in a 48 bit insn where the value to insert
|
||||
(say an immediate value) is the last 16 bits then word_length here
|
||||
would be 16. To handle a 24 bit insn with an 18 bit immediate,
|
||||
extract_1 handles 24 bits (using a combination of bfd_get8,16). */
|
||||
|
||||
if (total_length > 32)
|
||||
{
|
||||
int needed_width = start % 8 + length;
|
||||
int fetch_length = (needed_width <= 8 ? 8
|
||||
: needed_width <= 16 ? 16
|
||||
: 32);
|
||||
|
||||
if (CGEN_INSN_LSB0_P)
|
||||
{
|
||||
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
|
||||
{
|
||||
abort (); /* wip */
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset = start & ~7;
|
||||
|
||||
bufp += offset / 8;
|
||||
start -= offset;
|
||||
total_length -= offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
|
||||
{
|
||||
int offset = start & ~7;
|
||||
|
||||
bufp += offset / 8;
|
||||
start -= offset;
|
||||
total_length -= offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
abort (); /* wip */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: which bytes are being extracted have been lost. */
|
||||
value = extract_1 (od, ex_info, start, length, total_length, bufp);
|
||||
}
|
||||
|
||||
#endif /* ! CGEN_INT_INSN_P */
|
||||
|
||||
*valuep = value;
|
||||
|
||||
/* FIXME: for now */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Default print handler. */
|
||||
|
||||
static void
|
||||
print_normal (od, dis_info, value, attrs, pc, length)
|
||||
CGEN_OPCODE_DESC od;
|
||||
PTR dis_info;
|
||||
long value;
|
||||
unsigned int attrs;
|
||||
bfd_vma pc;
|
||||
int length;
|
||||
{
|
||||
disassemble_info *info = (disassemble_info *) dis_info;
|
||||
|
||||
#ifdef CGEN_PRINT_NORMAL
|
||||
CGEN_PRINT_NORMAL (od, info, value, attrs, pc, length);
|
||||
#endif
|
||||
|
||||
/* Print the operand as directed by the attributes. */
|
||||
if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_FAKE))
|
||||
; /* nothing to do */
|
||||
else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
|
||||
(*info->fprintf_func) (info->stream, "0x%lx", value);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "%ld", value);
|
||||
}
|
||||
|
||||
/* Default address handler. */
|
||||
|
||||
static void
|
||||
print_address (od, dis_info, value, attrs, pc, length)
|
||||
CGEN_OPCODE_DESC od;
|
||||
PTR dis_info;
|
||||
bfd_vma value;
|
||||
unsigned int attrs;
|
||||
bfd_vma pc;
|
||||
int length;
|
||||
{
|
||||
disassemble_info *info = (disassemble_info *) dis_info;
|
||||
|
||||
#ifdef CGEN_PRINT_ADDRESS
|
||||
CGEN_PRINT_ADDRESS (od, info, value, attrs, pc, length);
|
||||
#endif
|
||||
|
||||
/* Print the operand as directed by the attributes. */
|
||||
if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_FAKE))
|
||||
; /* 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_UNSIGNED))
|
||||
(*info->fprintf_func) (info->stream, "0x%lx", (long) value);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "%ld", (long) value);
|
||||
}
|
||||
|
||||
/* Keyword print handler. */
|
||||
|
||||
static void
|
||||
print_keyword (od, dis_info, keyword_table, value, attrs)
|
||||
CGEN_OPCODE_DESC od;
|
||||
PTR dis_info;
|
||||
CGEN_KEYWORD *keyword_table;
|
||||
long value;
|
||||
unsigned int attrs;
|
||||
{
|
||||
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 extractor.
|
||||
|
||||
INSN_VALUE is the first CGEN_BASE_INSN_SIZE bytes, 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 (od, insn, ex_info, insn_value, fields, pc)
|
||||
CGEN_OPCODE_DESC od;
|
||||
const CGEN_INSN *insn;
|
||||
CGEN_EXTRACT_INFO *ex_info;
|
||||
unsigned long insn_value;
|
||||
CGEN_FIELDS *fields;
|
||||
bfd_vma pc;
|
||||
{
|
||||
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
|
||||
const unsigned char *syn;
|
||||
|
||||
CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
|
||||
|
||||
CGEN_INIT_EXTRACT (od);
|
||||
|
||||
for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
|
||||
{
|
||||
int length;
|
||||
|
||||
if (CGEN_SYNTAX_CHAR_P (*syn))
|
||||
continue;
|
||||
|
||||
length = fr30_cgen_extract_operand (od, 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);
|
||||
}
|
||||
|
||||
/* Default insn printer.
|
||||
|
||||
DIS_INFO is defined as `PTR' so the disassembler needn't know anything
|
||||
about disassemble_info. */
|
||||
|
||||
static void
|
||||
print_insn_normal (od, dis_info, insn, fields, pc, length)
|
||||
CGEN_OPCODE_DESC od;
|
||||
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 unsigned char *syn;
|
||||
|
||||
CGEN_INIT_PRINT (od);
|
||||
|
||||
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. */
|
||||
fr30_cgen_print_operand (od, CGEN_SYNTAX_FIELD (*syn), info,
|
||||
fields, CGEN_INSN_ATTRS (insn), pc, length);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 (od, pc, info, buf, buflen)
|
||||
CGEN_OPCODE_DESC od;
|
||||
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;
|
||||
|
||||
ex_info.dis_info = info;
|
||||
ex_info.valid = (1 << CGEN_BASE_INSN_SIZE) - 1;
|
||||
ex_info.bytes = buf;
|
||||
|
||||
switch (buflen)
|
||||
{
|
||||
case 1:
|
||||
insn_value = buf[0];
|
||||
break;
|
||||
case 2:
|
||||
insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb16 (buf) : bfd_getl16 (buf);
|
||||
break;
|
||||
case 4:
|
||||
insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb32 (buf) : bfd_getl32 (buf);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* 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 (od, buf, insn_value);
|
||||
while (insn_list != NULL)
|
||||
{
|
||||
const CGEN_INSN *insn = insn_list->insn;
|
||||
CGEN_FIELDS fields;
|
||||
int length;
|
||||
|
||||
#if 0 /* not needed as insn shouldn't be in hash lists if not supported */
|
||||
/* Supported by this cpu? */
|
||||
if (! fr30_cgen_insn_supported (od, insn))
|
||||
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_MASK (insn)) == CGEN_INSN_VALUE (insn))
|
||||
{
|
||||
/* Printing is handled in two passes. The first pass parses the
|
||||
machine insn and extracts the fields. The second pass prints
|
||||
them. */
|
||||
|
||||
length = (*CGEN_EXTRACT_FN (insn)) (od, insn, &ex_info, insn_value,
|
||||
&fields, pc);
|
||||
/* length < 0 -> error */
|
||||
if (length < 0)
|
||||
return length;
|
||||
if (length > 0)
|
||||
{
|
||||
(*CGEN_PRINT_FN (insn)) (od, 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 (od, pc, info)
|
||||
CGEN_OPCODE_DESC od;
|
||||
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, CGEN_BASE_INSN_SIZE, info);
|
||||
if (status != 0)
|
||||
{
|
||||
(*info->memory_error_func) (status, pc, info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return print_insn (od, pc, info, buf, CGEN_BASE_INSN_SIZE);
|
||||
}
|
||||
|
||||
/* Main entry point.
|
||||
Print one instruction from PC on INFO->STREAM.
|
||||
Return the size of the instruction (in bytes). */
|
||||
|
||||
int
|
||||
print_insn_fr30 (pc, info)
|
||||
bfd_vma pc;
|
||||
disassemble_info *info;
|
||||
{
|
||||
int length;
|
||||
static CGEN_OPCODE_DESC od = 0;
|
||||
int mach = info->mach;
|
||||
int big_p = info->endian == BFD_ENDIAN_BIG;
|
||||
|
||||
/* If we haven't initialized yet, initialize the opcode table. */
|
||||
if (! od)
|
||||
{
|
||||
od = fr30_cgen_opcode_open (mach,
|
||||
big_p ?
|
||||
CGEN_ENDIAN_BIG
|
||||
: CGEN_ENDIAN_LITTLE);
|
||||
fr30_cgen_init_dis (od);
|
||||
}
|
||||
/* If we've switched cpu's, re-initialize. */
|
||||
/* ??? Perhaps we should use BFD_ENDIAN. */
|
||||
else if (mach != CGEN_OPCODE_MACH (od)
|
||||
|| (CGEN_OPCODE_ENDIAN (od)
|
||||
!= (big_p ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE)))
|
||||
{
|
||||
cgen_set_cpu (od, mach, big_p ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE);
|
||||
}
|
||||
|
||||
/* 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 (od, pc, info);
|
||||
if (length > 0)
|
||||
return length;
|
||||
if (length < 0)
|
||||
return -1;
|
||||
|
||||
(*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
|
||||
return CGEN_DEFAULT_INSN_SIZE;
|
||||
}
|
660
opcodes/fr30-opc.c
Normal file
660
opcodes/fr30-opc.c
Normal file
@ -0,0 +1,660 @@
|
||||
/* Generic opcode table support for targets using CGEN. -*- C -*-
|
||||
CGEN: Cpu tools GENerator
|
||||
|
||||
THIS FILE IS USED TO GENERATE fr30-opc.c.
|
||||
|
||||
Copyright (C) 1998 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. */
|
||||
|
||||
#include "sysdep.h"
|
||||
#include <stdio.h>
|
||||
#include "ansidecl.h"
|
||||
#include "libiberty.h"
|
||||
#include "bfd.h"
|
||||
#include "symcat.h"
|
||||
#include "fr30-opc.h"
|
||||
#include "opintl.h"
|
||||
|
||||
/* 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 *, unsigned long));
|
||||
|
||||
/* Cover function to read and properly byteswap an insn value. */
|
||||
|
||||
CGEN_INSN_INT
|
||||
cgen_get_insn_value (od, buf, length)
|
||||
CGEN_OPCODE_DESC od;
|
||||
unsigned char *buf;
|
||||
int length;
|
||||
{
|
||||
CGEN_INSN_INT value;
|
||||
|
||||
switch (length)
|
||||
{
|
||||
case 8:
|
||||
value = *buf;
|
||||
break;
|
||||
case 16:
|
||||
if (CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG)
|
||||
value = bfd_getb16 (buf);
|
||||
else
|
||||
value = bfd_getl16 (buf);
|
||||
break;
|
||||
case 32:
|
||||
if (CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG)
|
||||
value = bfd_getb32 (buf);
|
||||
else
|
||||
value = bfd_getl32 (buf);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Cover function to store an insn value properly byteswapped. */
|
||||
|
||||
void
|
||||
cgen_put_insn_value (od, buf, length, value)
|
||||
CGEN_OPCODE_DESC od;
|
||||
unsigned char *buf;
|
||||
int length;
|
||||
CGEN_INSN_INT value;
|
||||
{
|
||||
switch (length)
|
||||
{
|
||||
case 8:
|
||||
buf[0] = value;
|
||||
break;
|
||||
case 16:
|
||||
if (CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG)
|
||||
bfd_putb16 (value, buf);
|
||||
else
|
||||
bfd_putl16 (value, buf);
|
||||
break;
|
||||
case 32:
|
||||
if (CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG)
|
||||
bfd_putb32 (value, buf);
|
||||
else
|
||||
bfd_putl32 (value, buf);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Look up instruction INSN_VALUE and extract its fields.
|
||||
INSN, if non-null, is the insn table entry.
|
||||
Otherwise INSN_VALUE is examined to compute it.
|
||||
LENGTH is the bit length of INSN_VALUE if known, otherwise 0.
|
||||
0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
|
||||
If INSN != NULL, LENGTH must be valid.
|
||||
ALIAS_P is non-zero if alias insns are to be included in the search.
|
||||
|
||||
The result a pointer to the insn table entry, or NULL if the instruction
|
||||
wasn't recognized. */
|
||||
|
||||
const CGEN_INSN *
|
||||
fr30_cgen_lookup_insn (od, insn, insn_value, length, fields, alias_p)
|
||||
CGEN_OPCODE_DESC od;
|
||||
const CGEN_INSN *insn;
|
||||
CGEN_INSN_BYTES insn_value;
|
||||
int length;
|
||||
CGEN_FIELDS *fields;
|
||||
int alias_p;
|
||||
{
|
||||
unsigned char buf[16];
|
||||
unsigned char *bufp;
|
||||
unsigned int base_insn;
|
||||
#if CGEN_INT_INSN_P
|
||||
CGEN_EXTRACT_INFO *info = NULL;
|
||||
#else
|
||||
CGEN_EXTRACT_INFO ex_info;
|
||||
CGEN_EXTRACT_INFO *info = &ex_info;
|
||||
#endif
|
||||
|
||||
#if ! CGEN_INT_INSN_P
|
||||
ex_info.dis_info = NULL;
|
||||
ex_info.bytes = insn_value;
|
||||
ex_info.valid = -1;
|
||||
#endif
|
||||
|
||||
if (!insn)
|
||||
{
|
||||
const CGEN_INSN_LIST *insn_list;
|
||||
|
||||
#if CGEN_INT_INSN_P
|
||||
cgen_put_insn_value (od, buf, length, insn_value);
|
||||
bufp = buf;
|
||||
base_insn = insn_value; /*???*/
|
||||
#else
|
||||
base_insn = cgen_get_insn_value (od, buf, length);
|
||||
bufp = insn_value;
|
||||
#endif
|
||||
|
||||
/* 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 (od, bufp, base_insn);
|
||||
while (insn_list != NULL)
|
||||
{
|
||||
insn = insn_list->insn;
|
||||
|
||||
if (alias_p
|
||||
|| ! CGEN_INSN_ATTR (insn, CGEN_INSN_ALIAS))
|
||||
{
|
||||
/* Basic bit mask must be correct. */
|
||||
/* ??? May wish to allow target to defer this check until the
|
||||
extract handler. */
|
||||
if ((insn_value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn))
|
||||
{
|
||||
/* ??? 0 is passed for `pc' */
|
||||
int elength = (*CGEN_EXTRACT_FN (insn)) (od, insn, info,
|
||||
insn_value, fields,
|
||||
(bfd_vma) 0);
|
||||
if (elength > 0)
|
||||
{
|
||||
/* sanity check */
|
||||
if (length != 0 && length != elength)
|
||||
abort ();
|
||||
return insn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
insn_list = CGEN_DIS_NEXT_INSN (insn_list);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Sanity check: can't pass an alias insn if ! alias_p. */
|
||||
if (! alias_p
|
||||
&& CGEN_INSN_ATTR (insn, CGEN_INSN_ALIAS))
|
||||
abort ();
|
||||
/* Sanity check: length must be correct. */
|
||||
if (length != CGEN_INSN_BITSIZE (insn))
|
||||
abort ();
|
||||
|
||||
/* ??? 0 is passed for `pc' */
|
||||
length = (*CGEN_EXTRACT_FN (insn)) (od, insn, info, insn_value, fields,
|
||||
(bfd_vma) 0);
|
||||
/* Sanity check: must succeed.
|
||||
Could relax this later if it ever proves useful. */
|
||||
if (length == 0)
|
||||
abort ();
|
||||
return insn;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Fill in the operand instances used by INSN whose operands are FIELDS.
|
||||
INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
|
||||
in. */
|
||||
|
||||
void
|
||||
fr30_cgen_get_insn_operands (od, insn, fields, indices)
|
||||
CGEN_OPCODE_DESC od;
|
||||
const CGEN_INSN * insn;
|
||||
const CGEN_FIELDS * fields;
|
||||
int *indices;
|
||||
{
|
||||
const CGEN_OPERAND_INSTANCE *opinst;
|
||||
int i;
|
||||
|
||||
for (i = 0, opinst = CGEN_INSN_OPERANDS (insn);
|
||||
opinst != NULL
|
||||
&& CGEN_OPERAND_INSTANCE_TYPE (opinst) != CGEN_OPERAND_INSTANCE_END;
|
||||
++i, ++opinst)
|
||||
{
|
||||
const CGEN_OPERAND *op = CGEN_OPERAND_INSTANCE_OPERAND (opinst);
|
||||
if (op == NULL)
|
||||
indices[i] = CGEN_OPERAND_INSTANCE_INDEX (opinst);
|
||||
else
|
||||
indices[i] = fr30_cgen_get_int_operand (CGEN_OPERAND_INDEX (op),
|
||||
fields);
|
||||
}
|
||||
}
|
||||
|
||||
/* Cover function to fr30_cgen_get_insn_operands when either INSN or FIELDS
|
||||
isn't known.
|
||||
The INSN, INSN_VALUE, and LENGTH arguments are passed to
|
||||
fr30_cgen_lookup_insn unchanged.
|
||||
|
||||
The result is the insn table entry or NULL if the instruction wasn't
|
||||
recognized. */
|
||||
|
||||
const CGEN_INSN *
|
||||
fr30_cgen_lookup_get_insn_operands (od, insn, insn_value, length, indices)
|
||||
CGEN_OPCODE_DESC od;
|
||||
const CGEN_INSN *insn;
|
||||
CGEN_INSN_BYTES insn_value;
|
||||
int length;
|
||||
int *indices;
|
||||
{
|
||||
CGEN_FIELDS fields;
|
||||
|
||||
/* Pass non-zero for ALIAS_P only if INSN != NULL.
|
||||
If INSN == NULL, we want a real insn. */
|
||||
insn = fr30_cgen_lookup_insn (od, insn, insn_value, length, &fields,
|
||||
insn != NULL);
|
||||
if (! insn)
|
||||
return NULL;
|
||||
|
||||
fr30_cgen_get_insn_operands (od, insn, &fields, indices);
|
||||
return insn;
|
||||
}
|
||||
/* Attributes. */
|
||||
|
||||
static const CGEN_ATTR_ENTRY MACH_attr[] =
|
||||
{
|
||||
{ "base", MACH_BASE },
|
||||
{ "fr30", MACH_FR30 },
|
||||
{ "max", MACH_MAX },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
const CGEN_ATTR_TABLE fr30_cgen_hardware_attr_table[] =
|
||||
{
|
||||
{ "CACHE-ADDR", NULL },
|
||||
{ "PC", NULL },
|
||||
{ "PROFILE", NULL },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
const CGEN_ATTR_TABLE fr30_cgen_operand_attr_table[] =
|
||||
{
|
||||
{ "ABS-ADDR", NULL },
|
||||
{ "FAKE", NULL },
|
||||
{ "NEGATIVE", NULL },
|
||||
{ "PCREL-ADDR", NULL },
|
||||
{ "RELAX", NULL },
|
||||
{ "SIGN-OPT", NULL },
|
||||
{ "UNSIGNED", NULL },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
const CGEN_ATTR_TABLE fr30_cgen_insn_attr_table[] =
|
||||
{
|
||||
{ "ALIAS", NULL },
|
||||
{ "COND-CTI", NULL },
|
||||
{ "NO-DIS", NULL },
|
||||
{ "RELAX", NULL },
|
||||
{ "RELAXABLE", NULL },
|
||||
{ "SKIP-CTI", NULL },
|
||||
{ "UNCOND-CTI", NULL },
|
||||
{ "VIRTUAL", NULL },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_gr_entries[] =
|
||||
{
|
||||
{ "ac", 13 },
|
||||
{ "fp", 14 },
|
||||
{ "sp", 15 },
|
||||
{ "r0", 0 },
|
||||
{ "r1", 1 },
|
||||
{ "r2", 2 },
|
||||
{ "r3", 3 },
|
||||
{ "r4", 4 },
|
||||
{ "r5", 5 },
|
||||
{ "r6", 6 },
|
||||
{ "r7", 7 },
|
||||
{ "r8", 8 },
|
||||
{ "r9", 9 },
|
||||
{ "r10", 10 },
|
||||
{ "r11", 11 },
|
||||
{ "r12", 12 },
|
||||
{ "r13", 13 },
|
||||
{ "r14", 14 },
|
||||
{ "r15", 15 }
|
||||
};
|
||||
|
||||
CGEN_KEYWORD fr30_cgen_opval_h_gr =
|
||||
{
|
||||
& fr30_cgen_opval_h_gr_entries[0],
|
||||
19
|
||||
};
|
||||
|
||||
|
||||
/* The hardware table. */
|
||||
|
||||
#define HW_ENT(n) fr30_cgen_hw_entries[n]
|
||||
static const CGEN_HW_ENTRY fr30_cgen_hw_entries[] =
|
||||
{
|
||||
{ HW_H_PC, & HW_ENT (HW_H_PC + 1), "h-pc", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0|(1<<CGEN_HW_PROFILE)|(1<<CGEN_HW_PC), { 0 } } },
|
||||
{ HW_H_MEMORY, & HW_ENT (HW_H_MEMORY + 1), "h-memory", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0, { 0 } } },
|
||||
{ HW_H_SINT, & HW_ENT (HW_H_SINT + 1), "h-sint", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0, { 0 } } },
|
||||
{ HW_H_UINT, & HW_ENT (HW_H_UINT + 1), "h-uint", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0, { 0 } } },
|
||||
{ HW_H_ADDR, & HW_ENT (HW_H_ADDR + 1), "h-addr", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0, { 0 } } },
|
||||
{ HW_H_IADDR, & HW_ENT (HW_H_IADDR + 1), "h-iaddr", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0, { 0 } } },
|
||||
{ HW_H_GR, & HW_ENT (HW_H_GR + 1), "h-gr", CGEN_ASM_KEYWORD, (PTR) & fr30_cgen_opval_h_gr, { 0, 0|(1<<CGEN_HW_CACHE_ADDR)|(1<<CGEN_HW_PROFILE), { 0 } } },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* The operand table. */
|
||||
|
||||
#define OPERAND(op) CONCAT2 (FR30_OPERAND_,op)
|
||||
#define OP_ENT(op) fr30_cgen_operand_table[OPERAND (op)]
|
||||
|
||||
const CGEN_OPERAND fr30_cgen_operand_table[MAX_OPERANDS] =
|
||||
{
|
||||
/* pc: program counter */
|
||||
{ "pc", & HW_ENT (HW_H_PC), 0, 0,
|
||||
{ 0, 0|(1<<CGEN_OPERAND_FAKE), { 0 } } },
|
||||
/* Ri: destination register */
|
||||
{ "Ri", & HW_ENT (HW_H_GR), 12, 4,
|
||||
{ 0, 0|(1<<CGEN_OPERAND_UNSIGNED), { 0 } } },
|
||||
/* Rj: source register */
|
||||
{ "Rj", & HW_ENT (HW_H_GR), 8, 4,
|
||||
{ 0, 0|(1<<CGEN_OPERAND_UNSIGNED), { 0 } } },
|
||||
};
|
||||
|
||||
/* Operand references. */
|
||||
|
||||
#define INPUT CGEN_OPERAND_INSTANCE_INPUT
|
||||
#define OUTPUT CGEN_OPERAND_INSTANCE_OUTPUT
|
||||
|
||||
static const CGEN_OPERAND_INSTANCE fmt_ADD_ops[] = {
|
||||
{ INPUT, "Rj", & HW_ENT (HW_H_GR), CGEN_MODE_SI, & OP_ENT (RJ), 0 },
|
||||
{ INPUT, "Ri", & HW_ENT (HW_H_GR), CGEN_MODE_SI, & OP_ENT (RI), 0 },
|
||||
{ OUTPUT, "Ri", & HW_ENT (HW_H_GR), CGEN_MODE_SI, & OP_ENT (RI), 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#undef INPUT
|
||||
#undef OUTPUT
|
||||
|
||||
#define A(a) (1 << CONCAT2 (CGEN_INSN_,a))
|
||||
#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
|
||||
#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
|
||||
|
||||
/* The instruction table.
|
||||
This is currently non-static because the simulator accesses it
|
||||
directly. */
|
||||
|
||||
const CGEN_INSN fr30_cgen_insn_table_entries[MAX_INSNS] =
|
||||
{
|
||||
/* Special null first entry.
|
||||
A `num' value of zero is thus invalid.
|
||||
Also, the special `invalid' insn resides here. */
|
||||
{ { 0 }, 0 },
|
||||
/* ADD $Rj,$Ri */
|
||||
{
|
||||
{ 1, 1, 1, 1 },
|
||||
FR30_INSN_ADD, "ADD", "ADD",
|
||||
{ { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
|
||||
{ 16, 16, 0xff00 }, 0xa600,
|
||||
(PTR) & fmt_ADD_ops[0],
|
||||
{ 0, 0, { 0 } }
|
||||
},
|
||||
};
|
||||
|
||||
#undef A
|
||||
#undef MNEM
|
||||
#undef OP
|
||||
|
||||
static const CGEN_INSN_TABLE insn_table =
|
||||
{
|
||||
& fr30_cgen_insn_table_entries[0],
|
||||
sizeof (CGEN_INSN),
|
||||
MAX_INSNS,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Each non-simple macro entry points to an array of expansion possibilities. */
|
||||
|
||||
#define A(a) (1 << CONCAT2 (CGEN_INSN_,a))
|
||||
#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_INSN macro_insn_table_entries[] =
|
||||
{
|
||||
};
|
||||
|
||||
#undef A
|
||||
#undef MNEM
|
||||
#undef OP
|
||||
|
||||
static const CGEN_INSN_TABLE macro_insn_table =
|
||||
{
|
||||
& macro_insn_table_entries[0],
|
||||
sizeof (CGEN_INSN),
|
||||
(sizeof (macro_insn_table_entries) /
|
||||
sizeof (macro_insn_table_entries[0])),
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
init_tables ()
|
||||
{
|
||||
}
|
||||
|
||||
/* 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 (insn, CGEN_INSN_NO_DIS))
|
||||
return 0;
|
||||
return CGEN_DIS_HASH_P (insn);
|
||||
}
|
||||
|
||||
/* 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 insn's bytes in target order.
|
||||
VALUE is an integer of the first CGEN_BASE_INSN_BITSIZE bits,
|
||||
host order. */
|
||||
|
||||
static unsigned int
|
||||
dis_hash_insn (buf, value)
|
||||
const char * buf;
|
||||
unsigned long value;
|
||||
{
|
||||
return CGEN_DIS_HASH (buf, value);
|
||||
}
|
||||
|
||||
/* Initialize an opcode table and return a descriptor.
|
||||
It's much like opening a file, and must be the first function called. */
|
||||
|
||||
CGEN_OPCODE_DESC
|
||||
fr30_cgen_opcode_open (mach, endian)
|
||||
int mach;
|
||||
enum cgen_endian endian;
|
||||
{
|
||||
CGEN_OPCODE_TABLE * table = (CGEN_OPCODE_TABLE *) xmalloc (sizeof (CGEN_OPCODE_TABLE));
|
||||
static int init_p;
|
||||
|
||||
if (! init_p)
|
||||
{
|
||||
init_tables ();
|
||||
init_p = 1;
|
||||
}
|
||||
|
||||
memset (table, 0, sizeof (*table));
|
||||
|
||||
CGEN_OPCODE_MACH (table) = mach;
|
||||
CGEN_OPCODE_ENDIAN (table) = 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. */
|
||||
CGEN_OPCODE_INSN_ENDIAN (table) = endian;
|
||||
|
||||
CGEN_OPCODE_HW_LIST (table) = & fr30_cgen_hw_entries[0];
|
||||
|
||||
CGEN_OPCODE_OPERAND_TABLE (table) = & fr30_cgen_operand_table[0];
|
||||
|
||||
* CGEN_OPCODE_INSN_TABLE (table) = insn_table;
|
||||
|
||||
* CGEN_OPCODE_MACRO_INSN_TABLE (table) = macro_insn_table;
|
||||
|
||||
CGEN_OPCODE_ASM_HASH_P (table) = asm_hash_insn_p;
|
||||
CGEN_OPCODE_ASM_HASH (table) = asm_hash_insn;
|
||||
CGEN_OPCODE_ASM_HASH_SIZE (table) = CGEN_ASM_HASH_SIZE;
|
||||
|
||||
CGEN_OPCODE_DIS_HASH_P (table) = dis_hash_insn_p;
|
||||
CGEN_OPCODE_DIS_HASH (table) = dis_hash_insn;
|
||||
CGEN_OPCODE_DIS_HASH_SIZE (table) = CGEN_DIS_HASH_SIZE;
|
||||
|
||||
return (CGEN_OPCODE_DESC) table;
|
||||
}
|
||||
|
||||
/* Close an opcode table. */
|
||||
|
||||
void
|
||||
fr30_cgen_opcode_close (desc)
|
||||
CGEN_OPCODE_DESC desc;
|
||||
{
|
||||
free (desc);
|
||||
}
|
||||
|
||||
/* 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
|
||||
fr30_cgen_get_int_operand (opindex, fields)
|
||||
int opindex;
|
||||
const CGEN_FIELDS * fields;
|
||||
{
|
||||
int value;
|
||||
|
||||
switch (opindex)
|
||||
{
|
||||
case FR30_OPERAND_RI :
|
||||
value = fields->f_Ri;
|
||||
break;
|
||||
case FR30_OPERAND_RJ :
|
||||
value = fields->f_Rj;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* xgettext:c-format */
|
||||
fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
|
||||
opindex);
|
||||
abort ();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bfd_vma
|
||||
fr30_cgen_get_vma_operand (opindex, fields)
|
||||
int opindex;
|
||||
const CGEN_FIELDS * fields;
|
||||
{
|
||||
bfd_vma value;
|
||||
|
||||
switch (opindex)
|
||||
{
|
||||
case FR30_OPERAND_RI :
|
||||
value = fields->f_Ri;
|
||||
break;
|
||||
case FR30_OPERAND_RJ :
|
||||
value = fields->f_Rj;
|
||||
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
|
||||
fr30_cgen_set_int_operand (opindex, fields, value)
|
||||
int opindex;
|
||||
CGEN_FIELDS * fields;
|
||||
int value;
|
||||
{
|
||||
switch (opindex)
|
||||
{
|
||||
case FR30_OPERAND_RI :
|
||||
fields->f_Ri = value;
|
||||
break;
|
||||
case FR30_OPERAND_RJ :
|
||||
fields->f_Rj = value;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* xgettext:c-format */
|
||||
fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
|
||||
opindex);
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fr30_cgen_set_vma_operand (opindex, fields, value)
|
||||
int opindex;
|
||||
CGEN_FIELDS * fields;
|
||||
bfd_vma value;
|
||||
{
|
||||
switch (opindex)
|
||||
{
|
||||
case FR30_OPERAND_RI :
|
||||
fields->f_Ri = value;
|
||||
break;
|
||||
case FR30_OPERAND_RJ :
|
||||
fields->f_Rj = value;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* xgettext:c-format */
|
||||
fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
|
||||
opindex);
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
215
opcodes/fr30-opc.h
Normal file
215
opcodes/fr30-opc.h
Normal file
@ -0,0 +1,215 @@
|
||||
/* Instruction description for fr30.
|
||||
|
||||
THIS FILE IS MACHINE GENERATED WITH CGEN.
|
||||
|
||||
Copyright (C) 1996, 1997, 1998 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 FR30_OPC_H
|
||||
#define FR30_OPC_H
|
||||
|
||||
#define CGEN_ARCH fr30
|
||||
|
||||
/* Given symbol S, return fr30_cgen_<s>. */
|
||||
#define CGEN_SYM(s) CONCAT3 (fr30,_cgen_,s)
|
||||
|
||||
/* Selected cpu families. */
|
||||
#define HAVE_CPU_FR30BF
|
||||
|
||||
#define CGEN_INSN_LSB0_P 0
|
||||
#define CGEN_WORD_BITSIZE 32
|
||||
#define CGEN_DEFAULT_INSN_BITSIZE 16
|
||||
#define CGEN_BASE_INSN_BITSIZE 16
|
||||
#define CGEN_MIN_INSN_BITSIZE 16
|
||||
#define CGEN_MAX_INSN_BITSIZE 16
|
||||
#define CGEN_DEFAULT_INSN_SIZE (CGEN_DEFAULT_INSN_BITSIZE / 8)
|
||||
#define CGEN_BASE_INSN_SIZE (CGEN_BASE_INSN_BITSIZE / 8)
|
||||
#define CGEN_MIN_INSN_SIZE (CGEN_MIN_INSN_BITSIZE / 8)
|
||||
#define CGEN_MAX_INSN_SIZE (CGEN_MAX_INSN_BITSIZE / 8)
|
||||
#define CGEN_INT_INSN_P 1
|
||||
|
||||
/* FIXME: Need to compute CGEN_MAX_SYNTAX_BYTES. */
|
||||
|
||||
/* 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 operands any insn or macro-insn has. */
|
||||
#define CGEN_MAX_INSN_OPERANDS 16
|
||||
|
||||
/* Enums. */
|
||||
|
||||
/* Enum declaration for insn op1 enums. */
|
||||
typedef enum insn_op1 {
|
||||
OP1_0, OP1_1, OP1_2, OP1_3
|
||||
, OP1_4, OP1_5, OP1_6, OP1_7
|
||||
, OP1_8, OP1_9, OP1_A, OP1_B
|
||||
, OP1_C, OP1_D, OP1_E, OP1_F
|
||||
} INSN_OP1;
|
||||
|
||||
/* Enum declaration for insn op2 enums. */
|
||||
typedef enum insn_op2 {
|
||||
OP2_0, OP2_1, OP2_2, OP2_3
|
||||
, OP2_4, OP2_5, OP2_6, OP2_7
|
||||
, OP2_8, OP2_9, OP2_A, OP2_B
|
||||
, OP2_C, OP2_D, OP2_E, OP2_F
|
||||
} INSN_OP2;
|
||||
|
||||
/* Enum declaration for insn op3 enums. */
|
||||
typedef enum insn_op3 {
|
||||
OP3_0, OP3_1, OP3_2, OP3_3
|
||||
, OP3_4, OP3_5, OP3_6, OP3_7
|
||||
, OP3_8, OP3_9, OP3_A, OP3_B
|
||||
, OP3_C, OP3_D, OP3_E, OP3_F
|
||||
} INSN_OP3;
|
||||
|
||||
/* Enum declaration for insn op5 enums. */
|
||||
typedef enum insn_op5 {
|
||||
OP5_0, OP5_1
|
||||
} INSN_OP5;
|
||||
|
||||
/* Enum declaration for general registers. */
|
||||
typedef enum h_gr {
|
||||
H_GR_AC = 13, H_GR_FP = 14, H_GR_SP = 15, H_GR_R0 = 0
|
||||
, H_GR_R1 = 1, H_GR_R2 = 2, H_GR_R3 = 3, H_GR_R4 = 4
|
||||
, H_GR_R5 = 5, H_GR_R6 = 6, H_GR_R7 = 7, H_GR_R8 = 8
|
||||
, H_GR_R9 = 9, H_GR_R10 = 10, H_GR_R11 = 11, H_GR_R12 = 12
|
||||
, H_GR_R13 = 13, H_GR_R14 = 14, H_GR_R15 = 15
|
||||
} H_GR;
|
||||
|
||||
/* Enum declaration for fr30 operand types. */
|
||||
typedef enum cgen_operand_type {
|
||||
FR30_OPERAND_PC, FR30_OPERAND_RI, FR30_OPERAND_RJ, FR30_OPERAND_MAX
|
||||
} CGEN_OPERAND_TYPE;
|
||||
|
||||
/* Non-boolean attributes. */
|
||||
|
||||
/* Enum declaration for machine type selection. */
|
||||
typedef enum mach_attr {
|
||||
MACH_BASE, MACH_FR30, MACH_MAX
|
||||
} MACH_ATTR;
|
||||
|
||||
/* Number of architecture variants. */
|
||||
#define MAX_MACHS ((int) MACH_MAX)
|
||||
|
||||
/* Number of operands types. */
|
||||
#define MAX_OPERANDS ((int) FR30_OPERAND_MAX)
|
||||
|
||||
/* Maximum number of operands referenced by any insn. */
|
||||
#define MAX_OPERAND_INSTANCES 3
|
||||
|
||||
/* Hardware, operand and instruction attribute indices. */
|
||||
|
||||
/* Enum declaration for cgen_hw attrs. */
|
||||
typedef enum cgen_hw_attr {
|
||||
CGEN_HW_CACHE_ADDR, CGEN_HW_PC, CGEN_HW_PROFILE
|
||||
} CGEN_HW_ATTR;
|
||||
|
||||
/* Number of non-boolean elements in cgen_hw. */
|
||||
#define CGEN_HW_NBOOL_ATTRS ((int) CGEN_HW_CACHE_ADDR)
|
||||
|
||||
/* Enum declaration for cgen_operand attrs. */
|
||||
typedef enum cgen_operand_attr {
|
||||
CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_FAKE, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_PCREL_ADDR
|
||||
, CGEN_OPERAND_RELAX, CGEN_OPERAND_SIGN_OPT, CGEN_OPERAND_UNSIGNED
|
||||
} CGEN_OPERAND_ATTR;
|
||||
|
||||
/* Number of non-boolean elements in cgen_operand. */
|
||||
#define CGEN_OPERAND_NBOOL_ATTRS ((int) CGEN_OPERAND_ABS_ADDR)
|
||||
|
||||
/* Enum declaration for cgen_insn attrs. */
|
||||
typedef enum cgen_insn_attr {
|
||||
CGEN_INSN_ALIAS, CGEN_INSN_COND_CTI, CGEN_INSN_NO_DIS, CGEN_INSN_RELAX
|
||||
, CGEN_INSN_RELAXABLE, CGEN_INSN_SKIP_CTI, CGEN_INSN_UNCOND_CTI, CGEN_INSN_VIRTUAL
|
||||
} CGEN_INSN_ATTR;
|
||||
|
||||
/* Number of non-boolean elements in cgen_insn. */
|
||||
#define CGEN_INSN_NBOOL_ATTRS ((int) CGEN_INSN_ALIAS)
|
||||
|
||||
/* Enum declaration for fr30 instruction types. */
|
||||
typedef enum cgen_insn_type {
|
||||
FR30_INSN_INVALID, FR30_INSN_ADD, FR30_INSN_MAX
|
||||
} CGEN_INSN_TYPE;
|
||||
|
||||
/* Index of `invalid' insn place holder. */
|
||||
#define CGEN_INSN_INVALID FR30_INSN_INVALID
|
||||
/* Total number of insns in table. */
|
||||
#define MAX_INSNS ((int) FR30_INSN_MAX)
|
||||
|
||||
/* cgen.h uses things we just defined. */
|
||||
#include "opcode/cgen.h"
|
||||
|
||||
/* This struct records data prior to insertion or after extraction. */
|
||||
struct cgen_fields
|
||||
{
|
||||
long f_nil;
|
||||
long f_op1;
|
||||
long f_op2;
|
||||
long f_op3;
|
||||
long f_op5;
|
||||
long f_Rj;
|
||||
long f_Ri;
|
||||
long f_Rs;
|
||||
long f_u4;
|
||||
long f_i4;
|
||||
long f_m4;
|
||||
long f_u8;
|
||||
long f_i8;
|
||||
long f_o8;
|
||||
long f_rel8;
|
||||
long f_dir;
|
||||
long f_rlist;
|
||||
long f_rel11;
|
||||
int length;
|
||||
};
|
||||
|
||||
/* Attributes. */
|
||||
extern const CGEN_ATTR_TABLE fr30_cgen_hw_attr_table[];
|
||||
extern const CGEN_ATTR_TABLE fr30_cgen_operand_attr_table[];
|
||||
extern const CGEN_ATTR_TABLE fr30_cgen_insn_attr_table[];
|
||||
|
||||
/* Enum declaration for fr30 hardware types. */
|
||||
typedef enum hw_type {
|
||||
HW_H_PC, HW_H_MEMORY, HW_H_SINT, HW_H_UINT
|
||||
, HW_H_ADDR, HW_H_IADDR, HW_H_GR, HW_MAX
|
||||
} HW_TYPE;
|
||||
|
||||
#define MAX_HW ((int) HW_MAX)
|
||||
|
||||
/* Hardware decls. */
|
||||
|
||||
extern CGEN_KEYWORD fr30_cgen_opval_h_gr;
|
||||
|
||||
#define CGEN_INIT_PARSE(od) \
|
||||
{\
|
||||
}
|
||||
#define CGEN_INIT_INSERT(od) \
|
||||
{\
|
||||
}
|
||||
#define CGEN_INIT_EXTRACT(od) \
|
||||
{\
|
||||
}
|
||||
#define CGEN_INIT_PRINT(od) \
|
||||
{\
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* FR30_OPC_H */
|
Loading…
Reference in New Issue
Block a user