Add IP2k GAS and OPCODES support.

This commit is contained in:
Nick Clifton 2002-07-19 07:52:40 +00:00
parent ccaf4e0741
commit a40cbfa3c9
28 changed files with 6468 additions and 447 deletions

View File

@ -1,4 +1,29 @@
Wed Jul 17 00:30:13 CEST 2002 Jan Hubicka <jh@suse.cz>
2002-07-18 Denis Chertykov <denisc@overta.ru>
Frank Ch. Eigler <fche@redhat.com>
Alan Lehotsky <alehotsky@cygnus.com>
John Healy <jhealy@redhat.com>
Jeff Johnston <jjohnstn@redhat.com>
* configure.in: Add ip2k configuraton.
* configure: Regenerate.
* Makefile.am: Add ip2k configuraton.
* Makefile.in: Regenerate.
* configure: Regenerate.
* Makefile.in: Regenerate.
* config/tc-ip2k.c: New file.
* config/tc-ip2k.h: New files.
* NEWS: Mention new support.
* doc/Makefile.am (CPU_DOCS): Add c-ip2k.texi.
* doc/Makefile.in: Regenerate.
* doc/all.texi: Set IP2K
* doc/as.texinfo: Add IP2K description.
* doc/c-ip2k.texi: New file.
2002-07-19 Nick Clifton <nickc@cambridge.redhat.com>
* NEWS: Reformat to match style of other NEWS files.
2002-07-17 Jan Hubicka <jh@suse.cz>
* tc-i386.c (i386_align_code): Implement x86_64 neutral code fillers.

View File

@ -56,6 +56,7 @@ CPU_TYPES = \
i386 \
i860 \
i960 \
ip2k \
m32r \
m68hc11 \
m68k \
@ -246,6 +247,7 @@ TARGET_CPU_CFILES = \
config/tc-i386.c \
config/tc-i860.c \
config/tc-i960.c \
config/tc-ip2k.c \
config/tc-m32r.c \
config/tc-m68hc11.c \
config/tc-m68k.c \
@ -295,6 +297,7 @@ TARGET_CPU_HFILES = \
config/tc-i386.h \
config/tc-i860.h \
config/tc-i960.h \
config/tc-ip2k.h \
config/tc-m32r.h \
config/tc-m68hc11.h \
config/tc-m68k.h \
@ -1163,6 +1166,12 @@ DEPTC_i960_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h \
$(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h $(INCDIR)/opcode/i960.h
DEPTC_ip2k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h \
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
$(srcdir)/../opcodes/ip2k-desc.h $(INCDIR)/opcode/cgen.h \
$(srcdir)/../opcodes/ip2k-opc.h cgen.h
DEPTC_m32r_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
$(srcdir)/config/tc-m32r.h $(INCDIR)/coff/internal.h \
$(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
@ -1681,6 +1690,11 @@ DEPOBJ_i960_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h \
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
struc-symbol.h $(INCDIR)/aout/aout64.h
DEPOBJ_ip2k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h \
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
struc-symbol.h $(INCDIR)/aout/aout64.h
DEPOBJ_m32r_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
$(srcdir)/config/tc-m32r.h $(INCDIR)/coff/internal.h \
$(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
@ -2101,6 +2115,9 @@ DEP_i960_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i960.h \
DEP_i960_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h
DEP_ip2k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h
DEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \
$(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
$(INCDIR)/bfdlink.h

View File

@ -167,6 +167,7 @@ CPU_TYPES = \
i386 \
i860 \
i960 \
ip2k \
m32r \
m68hc11 \
m68k \
@ -363,6 +364,7 @@ TARGET_CPU_CFILES = \
config/tc-i386.c \
config/tc-i860.c \
config/tc-i960.c \
config/tc-ip2k.c \
config/tc-m32r.c \
config/tc-m68hc11.c \
config/tc-m68k.c \
@ -413,6 +415,7 @@ TARGET_CPU_HFILES = \
config/tc-i386.h \
config/tc-i860.h \
config/tc-i960.h \
config/tc-ip2k.h \
config/tc-m32r.h \
config/tc-m68hc11.h \
config/tc-m68k.h \
@ -910,6 +913,13 @@ DEPTC_i960_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h \
$(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h $(INCDIR)/opcode/i960.h
DEPTC_ip2k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h \
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
$(srcdir)/../opcodes/ip2k-desc.h $(INCDIR)/opcode/cgen.h \
$(srcdir)/../opcodes/ip2k-opc.h cgen.h
DEPTC_m32r_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
$(srcdir)/config/tc-m32r.h $(INCDIR)/coff/internal.h \
$(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h \
@ -1539,6 +1549,12 @@ DEPOBJ_i960_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
struc-symbol.h $(INCDIR)/aout/aout64.h
DEPOBJ_ip2k_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h \
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
struc-symbol.h $(INCDIR)/aout/aout64.h
DEPOBJ_m32r_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
$(srcdir)/config/tc-m32r.h $(INCDIR)/coff/internal.h \
$(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
@ -2069,6 +2085,10 @@ DEP_i960_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h
DEP_ip2k_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h
DEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \
$(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
$(INCDIR)/bfdlink.h
@ -2380,7 +2400,7 @@ configure configure.in gdbinit.in itbl-lex.c itbl-parse.c
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
TAR = gtar
GZIP_ENV = --best
SOURCES = $(gasp_new_SOURCES) $(itbl_test_SOURCES) $(as_new_SOURCES) $(EXTRA_as_new_SOURCES)
OBJECTS = $(gasp_new_OBJECTS) $(itbl_test_OBJECTS) $(as_new_OBJECTS)

436
gas/NEWS
View File

@ -1,370 +1,366 @@
-*- text -*-
* Support for the Ubicom IP2xxx microcontroller added.
Changes in 2.13:
Support for the Fujitsu FRV architecture added by Red Hat. Models for FR400 and
FR500 included.
* Support for the Fujitsu FRV architecture added by Red Hat. Models for FR400
and FR500 included.
Support for DLX processor added.
* Support for DLX processor added.
GASP has now been deprecated and will be removed in a future release. Use the
macro facilities in GAS instead.
* GASP has now been deprecated and will be removed in a future release. Use
the macro facilities in GAS instead.
GASP now correctly parses floating point numbers. Unless the base is explicitly
specified, they are interpreted as decimal numbers regardless of the currently
specified base.
* GASP now correctly parses floating point numbers. Unless the base is
explicitly specified, they are interpreted as decimal numbers regardless of
the currently specified base.
Changes in 2.12:
Support for Don Knuth's MMIX, by Hans-Peter Nilsson.
* Support for Don Knuth's MMIX, by Hans-Peter Nilsson.
Support for the OpenRISC 32-bit embedded processor by OpenCores.
* Support for the OpenRISC 32-bit embedded processor by OpenCores.
The ARM assembler now accepts -march=..., -mcpu=... and -mfpu=... for
specifying the target instruction set. The old method of specifying the
target processor has been deprecated, but is still accepted for
compatibility.
* The ARM assembler now accepts -march=..., -mcpu=... and -mfpu=... for
specifying the target instruction set. The old method of specifying the
target processor has been deprecated, but is still accepted for
compatibility.
Support for the VFP floating-point instruction set has been added to
the ARM assembler.
* Support for the VFP floating-point instruction set has been added to
the ARM assembler.
New psuedo op: .incbin to include a set of binary data at a given point
in the assembly. Contributed by Anders Norlander.
* New psuedo op: .incbin to include a set of binary data at a given point
in the assembly. Contributed by Anders Norlander.
The MIPS assembler now accepts -march/-mtune. -mcpu has been deprecated
but still works for compatability.
* The MIPS assembler now accepts -march/-mtune. -mcpu has been deprecated
but still works for compatability.
The MIPS assembler no longer issues a warning by default when it
generates a nop instruction from a macro. The new command line option
-n will turn on the warning.
* The MIPS assembler no longer issues a warning by default when it
generates a nop instruction from a macro. The new command line option
-n will turn on the warning.
Changes in 2.11:
x86 gas now supports the full Pentium4 instruction set.
* x86 gas now supports the full Pentium4 instruction set.
Support for AMD x86-64 architecture, by Jan Hubicka, SuSE Labs.
* Support for AMD x86-64 architecture, by Jan Hubicka, SuSE Labs.
Support for Motorola 68HC11 and 68HC12.
* Support for Motorola 68HC11 and 68HC12.
Support for Texas Instruments TMS320C54x (tic54x).
* Support for Texas Instruments TMS320C54x (tic54x).
Support for IA-64.
* Support for IA-64.
Support for i860, by Jason Eckhardt.
* Support for i860, by Jason Eckhardt.
Support for CRIS (Axis Communications ETRAX series).
* Support for CRIS (Axis Communications ETRAX series).
x86 gas has a new .arch pseudo op to specify the target CPU architecture.
* x86 gas has a new .arch pseudo op to specify the target CPU architecture.
x86 gas -q command line option quietens warnings about register size changes
due to suffix, indirect jmp/call without `*', stand-alone prefixes, and
translating various deprecated floating point instructions.
* x86 gas -q command line option quietens warnings about register size changes
due to suffix, indirect jmp/call without `*', stand-alone prefixes, and
translating various deprecated floating point instructions.
Changes in 2.10:
Support for the ARM msr instruction was changed to only allow an immediate
operand when altering the flags field.
* Support for the ARM msr instruction was changed to only allow an immediate
operand when altering the flags field.
Support for ATMEL AVR.
* Support for ATMEL AVR.
Support for IBM 370 ELF. Somewhat experimental.
* Support for IBM 370 ELF. Somewhat experimental.
Support for numbers with suffixes.
* Support for numbers with suffixes.
Added support for breaking to the end of repeat loops.
* Added support for breaking to the end of repeat loops.
Added support for parallel instruction syntax (DOUBLEBAR_PARALLEL).
* Added support for parallel instruction syntax (DOUBLEBAR_PARALLEL).
New .elseif pseudo-op added.
* New .elseif pseudo-op added.
New --fatal-warnings option.
* New --fatal-warnings option.
picoJava architecture support added.
* picoJava architecture support added.
Motorola MCore 210 processor support added.
* Motorola MCore 210 processor support added.
A new pseudo-op .intel_syntax has been implemented to allow gas to parse i386
assembly programs with intel syntax.
* A new pseudo-op .intel_syntax has been implemented to allow gas to parse i386
assembly programs with intel syntax.
New pseudo-ops .func,.endfunc to aid in debugging user-written assembler code.
* New pseudo-ops .func,.endfunc to aid in debugging user-written assembler code.
Added -gdwarf2 option to generate DWARF 2 debugging information.
* Added -gdwarf2 option to generate DWARF 2 debugging information.
Full 16-bit mode support for i386.
* Full 16-bit mode support for i386.
Greatly improved instruction operand checking for i386. This change will
produce errors or warnings on incorrect assembly code that previous versions of
gas accepted. If you get unexpected messages from code that worked with older
versions of gas, please double check the code before reporting a bug.
* Greatly improved instruction operand checking for i386. This change will
produce errors or warnings on incorrect assembly code that previous versions
of gas accepted. If you get unexpected messages from code that worked with
older versions of gas, please double check the code before reporting a bug.
Weak symbol support added for COFF targets.
* Weak symbol support added for COFF targets.
Mitsubishi D30V support added.
* Mitsubishi D30V support added.
Texas Instruments c80 (tms320c80) support added.
* Texas Instruments c80 (tms320c80) support added.
i960 ELF support added.
* i960 ELF support added.
ARM ELF support added.
* ARM ELF support added.
Changes in 2.9:
Texas Instruments c30 (tms320c30) support added.
* Texas Instruments c30 (tms320c30) support added.
The assembler now optimizes the exception frame information generated by egcs
and gcc 2.8. The new --traditional-format option disables this optimization.
* The assembler now optimizes the exception frame information generated by egcs
and gcc 2.8. The new --traditional-format option disables this optimization.
Added --gstabs option to generate stabs debugging information.
* Added --gstabs option to generate stabs debugging information.
The -a option takes a new suboption, m (e.g., -alm) to expand macros in a
listing.
* The -a option takes a new suboption, m (e.g., -alm) to expand macros in a
listing.
Added -MD option to print dependencies.
* Added -MD option to print dependencies.
Changes in 2.8:
BeOS support added.
* BeOS support added.
MIPS16 support added.
* MIPS16 support added.
Motorola ColdFire 5200 support added (configure for m68k and use -m5200).
* Motorola ColdFire 5200 support added (configure for m68k and use -m5200).
Alpha/VMS support added.
* Alpha/VMS support added.
m68k options --base-size-default-16, --base-size-default-32,
--disp-size-default-16, and --disp-size-default-32 added.
* m68k options --base-size-default-16, --base-size-default-32,
--disp-size-default-16, and --disp-size-default-32 added.
The alignment directives now take an optional third argument, which is the
maximum number of bytes to skip. If doing the alignment would require skipping
more than the given number of bytes, the alignment is not done at all.
* The alignment directives now take an optional third argument, which is the
maximum number of bytes to skip. If doing the alignment would require
skipping more than the given number of bytes, the alignment is not done at
all.
The ELF assembler has a new pseudo-op, .symver, used for symbol versioning.
* The ELF assembler has a new pseudo-op, .symver, used for symbol versioning.
The -a option takes a new suboption, c (e.g., -alc), to skip false conditionals
in listings.
* The -a option takes a new suboption, c (e.g., -alc), to skip false
conditionals in listings.
Added new pseudo-op, .equiv; it's like .equ, except that it is an error if the
symbol is already defined.
* Added new pseudo-op, .equiv; it's like .equ, except that it is an error if
the symbol is already defined.
Changes in 2.7:
The PowerPC assembler now allows the use of symbolic register names (r0, etc.)
if -mregnames is used. Symbolic names preceded by a '%' (%r0, etc.) can be
used any time. PowerPC 860 move to/from SPR instructions have been added.
* The PowerPC assembler now allows the use of symbolic register names (r0,
etc.) if -mregnames is used. Symbolic names preceded by a '%' (%r0, etc.)
can be used any time. PowerPC 860 move to/from SPR instructions have been
added.
Alpha Linux (ELF) support added.
* Alpha Linux (ELF) support added.
PowerPC ELF support added.
* PowerPC ELF support added.
m68k Linux (ELF) support added.
* m68k Linux (ELF) support added.
i960 Hx/Jx support added.
* i960 Hx/Jx support added.
i386/PowerPC gnu-win32 support added.
* i386/PowerPC gnu-win32 support added.
SCO ELF support added. For OpenServer 5 targets (i386-unknown-sco3.2v5) the
default is to build COFF-only support. To get a set of tools that generate ELF
(they'll understand both COFF and ELF), you must configure with
target=i386-unknown-sco3.2v5elf.
* SCO ELF support added. For OpenServer 5 targets (i386-unknown-sco3.2v5) the
default is to build COFF-only support. To get a set of tools that generate
ELF (they'll understand both COFF and ELF), you must configure with
target=i386-unknown-sco3.2v5elf.
m88k-motorola-sysv3* support added.
* m88k-motorola-sysv3* support added.
Changes in 2.6:
Gas now directly supports macros, without requiring GASP.
* Gas now directly supports macros, without requiring GASP.
Gas now has an MRI assembler compatibility mode. Use -M or --mri to select MRI
mode. The pseudo-op ``.mri 1'' will switch into the MRI mode until the ``.mri
0'' is seen; this can be convenient for inline assembler code.
* Gas now has an MRI assembler compatibility mode. Use -M or --mri to select
MRI mode. The pseudo-op ``.mri 1'' will switch into the MRI mode until the
``.mri 0'' is seen; this can be convenient for inline assembler code.
Added --defsym SYM=VALUE option.
* Added --defsym SYM=VALUE option.
Added -mips4 support to MIPS assembler.
* Added -mips4 support to MIPS assembler.
Added PIC support to Solaris and SPARC SunOS 4 assembler.
* Added PIC support to Solaris and SPARC SunOS 4 assembler.
Changes in 2.4:
Converted this directory to use an autoconf-generated configure script.
* Converted this directory to use an autoconf-generated configure script.
ARM support, from Richard Earnshaw.
* ARM support, from Richard Earnshaw.
Updated VMS support, from Pat Rankin, including considerably improved debugging
support.
* Updated VMS support, from Pat Rankin, including considerably improved
debugging support.
Support for the control registers in the 68060.
* Support for the control registers in the 68060.
Handles (ignores) a new directive ".this_GCC_requires_the_GNU_assembler", to
provide for possible future gcc changes, for targets where gas provides some
features not available in the native assembler. If the native assembler is
used, it should become obvious pretty quickly what the problem is.
* Handles (ignores) a new directive ".this_GCC_requires_the_GNU_assembler", to
provide for possible future gcc changes, for targets where gas provides some
features not available in the native assembler. If the native assembler is
used, it should become obvious pretty quickly what the problem is.
Usage message is available with "--help".
* Usage message is available with "--help".
The GNU Assembler Preprocessor (gasp) is included. (Actually, it was in 2.3
also, but didn't get into the NEWS file.)
* The GNU Assembler Preprocessor (gasp) is included. (Actually, it was in 2.3
also, but didn't get into the NEWS file.)
Weak symbol support for a.out.
* Weak symbol support for a.out.
A bug in the listing code which could cause an infinite loop has been fixed.
Bugs in listings when generating a COFF object file have also been fixed.
* A bug in the listing code which could cause an infinite loop has been fixed.
Bugs in listings when generating a COFF object file have also been fixed.
Initial i386-svr4 PIC implementation from Eric Youngdale, based on code by Paul
Kranenburg.
* Initial i386-svr4 PIC implementation from Eric Youngdale, based on code by
Paul Kranenburg.
Improved Alpha support. Immediate constants can have a much larger range now.
Support for the 21164 has been contributed by Digital.
* Improved Alpha support. Immediate constants can have a much larger range
now. Support for the 21164 has been contributed by Digital.
Updated ns32k (pc532-mach, netbsd532) support from Ian Dall.
* Updated ns32k (pc532-mach, netbsd532) support from Ian Dall.
Changes in 2.3:
Mach i386 support, by David Mackenzie and Ken Raeburn.
* Mach i386 support, by David Mackenzie and Ken Raeburn.
RS/6000 and PowerPC support by Ian Taylor.
* RS/6000 and PowerPC support by Ian Taylor.
VMS command scripts (make-gas.com, config-gas.com) have been worked on a bit,
based on mail received from various people. The `-h#' option should work again
too.
* VMS command scripts (make-gas.com, config-gas.com) have been worked on a bit,
based on mail received from various people. The `-h#' option should work
again too.
HP-PA work, by Jeff Law. Note, for the PA, gas-2.3 has been designed to work
with gdb-4.12 and gcc-2.6. As gcc-2.6 has not been released yet, a special
version of gcc-2.5.8 has been patched to work with gas-2.3. You can retrieve
this special version of gcc-2.5.8 via anonymous ftp from jaguar.cs.utah.edu
in the "dist" directory.
* HP-PA work, by Jeff Law. Note, for the PA, gas-2.3 has been designed to work
with gdb-4.12 and gcc-2.6. As gcc-2.6 has not been released yet, a special
version of gcc-2.5.8 has been patched to work with gas-2.3. You can retrieve
this special version of gcc-2.5.8 via anonymous ftp from jaguar.cs.utah.edu
in the "dist" directory.
Vax support in gas fixed for BSD, so it builds and seems to run a couple simple
tests okay. I haven't put it through extensive testing. (GNU make is
currently required for BSD 4.3 builds.)
* Vax support in gas fixed for BSD, so it builds and seems to run a couple
simple tests okay. I haven't put it through extensive testing. (GNU make is
currently required for BSD 4.3 builds.)
Support for the DEC Alpha, running OSF/1 (ECOFF format). The gas support is
based on code donated by CMU, which used an a.out-based format. I'm afraid the
alpha-a.out support is pretty badly mangled, and much of it removed; making it
work will require rewriting it as BFD support for the format anyways.
* Support for the DEC Alpha, running OSF/1 (ECOFF format). The gas support is
based on code donated by CMU, which used an a.out-based format. I'm afraid
the alpha-a.out support is pretty badly mangled, and much of it removed;
making it work will require rewriting it as BFD support for the format anyways.
Irix 5 support.
* Irix 5 support.
The test suites have been fixed up a bit, so that they should work with a
couple different versions of expect and dejagnu.
* The test suites have been fixed up a bit, so that they should work with a
couple different versions of expect and dejagnu.
Symbols' values are now handled internally as expressions, permitting more
flexibility in evaluating them in some cases. Some details of relocation
handling have also changed, and simple constant pool management has been added,
to make the Alpha port easier.
* Symbols' values are now handled internally as expressions, permitting more
flexibility in evaluating them in some cases. Some details of relocation
handling have also changed, and simple constant pool management has been
added, to make the Alpha port easier.
New option "--statistics" for printing out program run times. This is intended
to be used with the gcc "-Q" option, which prints out times spent in various
phases of compilation. (You should be able to get all of them printed out with
"gcc -Q -Wa,--statistics", I think.)
----------------------------------------------------------------
* New option "--statistics" for printing out program run times. This is
intended to be used with the gcc "-Q" option, which prints out times spent in
various phases of compilation. (You should be able to get all of them
printed out with "gcc -Q -Wa,--statistics", I think.)
Changes in 2.2:
RS/6000 AIX and MIPS SGI Irix 5 support has been added.
* RS/6000 AIX and MIPS SGI Irix 5 support has been added.
Configurations that are still in development (and therefore are convenient to
have listed in configure.in) still get rejected without a minor change to
gas/Makefile.in, so people not doing development work shouldn't get the
impression that support for such configurations is actually believed to be
reliable.
* Configurations that are still in development (and therefore are convenient to
have listed in configure.in) still get rejected without a minor change to
gas/Makefile.in, so people not doing development work shouldn't get the
impression that support for such configurations is actually believed to be
reliable.
The program name (usually "as") is printed when a fatal error message is
displayed. This should prevent some confusion about the source of occasional
messages about "internal errors".
* The program name (usually "as") is printed when a fatal error message is
displayed. This should prevent some confusion about the source of occasional
messages about "internal errors".
ELF support is falling into place. Support for the 386 should be working.
Support for SPARC Solaris is in. HPPA support from Utah is being integrated.
* ELF support is falling into place. Support for the 386 should be working.
Support for SPARC Solaris is in. HPPA support from Utah is being integrated.
Symbol values are maintained as expressions instead of being immediately boiled
down to add-symbol, sub-symbol, and constant. This permits slightly more
complex calculations involving symbols whose values are not alreadey known.
* Symbol values are maintained as expressions instead of being immediately
boiled down to add-symbol, sub-symbol, and constant. This permits slightly
more complex calculations involving symbols whose values are not alreadey
known.
DBX-style debugging info ("stabs") is now supported for COFF formats.
If any stabs directives are seen in the source, GAS will create two new
sections: a ".stab" and a ".stabstr" section. The format of the .stab
section is nearly identical to the a.out symbol format, and .stabstr is
its string table. For this to be useful, you must have configured GCC
to generate stabs (by defining DBX_DEBUGGING_INFO), and must have a GDB
that can use the stab sections (4.11 or later).
* DBX-style debugging info ("stabs") is now supported for COFF formats.
If any stabs directives are seen in the source, GAS will create two new
sections: a ".stab" and a ".stabstr" section. The format of the .stab
section is nearly identical to the a.out symbol format, and .stabstr is
its string table. For this to be useful, you must have configured GCC
to generate stabs (by defining DBX_DEBUGGING_INFO), and must have a GDB
that can use the stab sections (4.11 or later).
LynxOS, on i386 and m68k platforms, is now supported. SPARC LynxOS
support is in progress.
----------------------------------------------------------------
* LynxOS, on i386 and m68k platforms, is now supported. SPARC LynxOS
support is in progress.
Changes in 2.1:
Several small fixes for i386-aix (PS/2) support from Minh Tran-Le have been
incorporated, but not well tested yet.
* Several small fixes for i386-aix (PS/2) support from Minh Tran-Le have been
incorporated, but not well tested yet.
Altered the opcode table split for m68k; it should require less VM to compile
with gcc now.
* Altered the opcode table split for m68k; it should require less VM to compile
with gcc now.
Some minor adjustments to add (Convergent Technologies') Miniframe support,
suggested by Ronald Cole.
* Some minor adjustments to add (Convergent Technologies') Miniframe support,
suggested by Ronald Cole.
HPPA support (running OSF only, not HPUX) has been contributed by Utah. This
includes improved ELF support, which I've started adapting for SPARC Solaris
2.x. Integration isn't completely, so it probably won't work.
* HPPA support (running OSF only, not HPUX) has been contributed by Utah. This
includes improved ELF support, which I've started adapting for SPARC Solaris
2.x. Integration isn't completely, so it probably won't work.
HP9000/300 support, donated by HP, has been merged in.
* HP9000/300 support, donated by HP, has been merged in.
Ian Taylor has finished the MIPS ECOFF (Ultrix, Irix) support.
* Ian Taylor has finished the MIPS ECOFF (Ultrix, Irix) support.
Better error messages for unsupported configurations (e.g., hppa-hpux).
* Better error messages for unsupported configurations (e.g., hppa-hpux).
Test suite framework is starting to become reasonable.
----------------------------------------------------------------
* Test suite framework is starting to become reasonable.
Changes in 2.0:
Mostly bug fixes.
* Mostly bug fixes.
Some more merging of BFD and ELF code, but ELF still doesn't work.
----------------------------------------------------------------
* Some more merging of BFD and ELF code, but ELF still doesn't work.
Changes in 1.94:
BFD merge is partly done. Adventurous souls may try giving configure the
"--with-bfd-assembler" option. Currently, ELF format requires it, a.out format
accepts it; SPARC CPU accepts it. It's the default only for OS "elf" or
"solaris". (ELF isn't really supported yet. It needs work. I've got some
code from Utah for HP-PA ELF, and from DG for m88k ELF, but they're not fully
merged yet.)
* BFD merge is partly done. Adventurous souls may try giving configure the
"--with-bfd-assembler" option. Currently, ELF format requires it, a.out
format accepts it; SPARC CPU accepts it. It's the default only for OS "elf"
or "solaris". (ELF isn't really supported yet. It needs work. I've got
some code from Utah for HP-PA ELF, and from DG for m88k ELF, but they're not
fully merged yet.)
The 68K opcode table has been split in half. It should now compile under gcc
without consuming ridiculous amounts of memory.
* The 68K opcode table has been split in half. It should now compile under gcc
without consuming ridiculous amounts of memory.
A couple data structures have been reduced in size. This should result in
saving a little bit of space at runtime.
* A couple data structures have been reduced in size. This should result in
saving a little bit of space at runtime.
Support for MIPS, from OSF and Ralph Campbell, has been merged in. The OSF
code provided ROSE format support, which I haven't merged in yet. (I can make
it available, if anyone wants to try it out.) Ralph's code, for BSD 4.4,
supports a.out format. We don't have ECOFF support in just yet; it's coming.
* Support for MIPS, from OSF and Ralph Campbell, has been merged in. The OSF
code provided ROSE format support, which I haven't merged in yet. (I can
make it available, if anyone wants to try it out.) Ralph's code, for BSD
4.4, supports a.out format. We don't have ECOFF support in just yet; it's
coming.
Support for the Hitachi H8/500 has been added.
* Support for the Hitachi H8/500 has been added.
VMS host and target support should be working now, thanks chiefly to Eric
Youngdale.
----------------------------------------------------------------
* VMS host and target support should be working now, thanks chiefly to Eric
Youngdale.
Changes in 1.93.01:
For m68k, support for more processors has been added: 68040, CPU32, 68851.
* For m68k, support for more processors has been added: 68040, CPU32, 68851.
For i386, .align is now power-of-two; was number-of-bytes.
* For i386, .align is now power-of-two; was number-of-bytes.
For m68k, "%" is now accepted before register names. For COFF format, which
doesn't use underscore prefixes for C labels, it is required, so variable "a0"
can be distinguished from the register.
* For m68k, "%" is now accepted before register names. For COFF format, which
doesn't use underscore prefixes for C labels, it is required, so variable "a0"
can be distinguished from the register.
Last public release was 1.38. Lots of configuration changes since then, lots
of new CPUs and formats, lots of bugs fixed.
* Last public release was 1.38. Lots of configuration changes since then, lots
of new CPUs and formats, lots of bugs fixed.
Local variables:

507
gas/config/tc-ip2k.c Normal file
View File

@ -0,0 +1,507 @@
/* tc-ip2k.c -- Assembler for the Scenix IP2xxx.
Copyright (C) 2000, 2002 Free Software Foundation.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include <ctype.h>
#include "as.h"
#include "dwarf2dbg.h"
#include "subsegs.h"
#include "symcat.h"
#include "opcodes/ip2k-desc.h"
#include "opcodes/ip2k-opc.h"
#include "cgen.h"
#include "elf/common.h"
#include "elf/ip2k.h"
#include "libbfd.h"
/* Structure to hold all of the different components describing
an individual instruction. */
typedef struct
{
const CGEN_INSN * insn;
const CGEN_INSN * orig_insn;
CGEN_FIELDS fields;
#if CGEN_INT_INSN_P
CGEN_INSN_INT buffer [1];
#define INSN_VALUE(buf) (*(buf))
#else
unsigned char buffer [CGEN_MAX_INSN_SIZE];
#define INSN_VALUE(buf) (buf)
#endif
char * addr;
fragS * frag;
int num_fixups;
fixS * fixups [GAS_CGEN_MAX_FIXUPS];
int indices [MAX_OPERAND_INSTANCES];
}
ip2k_insn;
const char comment_chars[] = ";";
const char line_comment_chars[] = "#";
const char line_separator_chars[] = "";
const char EXP_CHARS[] = "eE";
const char FLT_CHARS[] = "dD";
static void ip2k_elf_section_text (int);
static void ip2k_elf_section_rtn (int);
/* The target specific pseudo-ops which we support. */
const pseudo_typeS md_pseudo_table[] =
{
{ "file", dwarf2_directive_file, 0 },
{ "loc", dwarf2_directive_loc, 0 },
{ "text", ip2k_elf_section_text, 0 },
{ "sect", ip2k_elf_section_rtn, 0 },
{ NULL, NULL, 0 }
};
#define OPTION_CPU_IP2022 (OPTION_MD_BASE)
#define OPTION_CPU_IP2022EXT (OPTION_MD_BASE+1)
struct option md_longopts[] =
{
{ "mip2022", no_argument, NULL, OPTION_CPU_IP2022 },
{ "mip2022ext", no_argument, NULL, OPTION_CPU_IP2022EXT },
{ NULL, no_argument, NULL, 0 },
};
size_t md_longopts_size = sizeof (md_longopts);
const char * md_shortopts = "";
/* Flag to detect when switching to code section where insn alignment is
implied. */
static int force_code_align = 0;
/* Mach selected from command line. */
int ip2k_mach = 0;
unsigned ip2k_mach_bitmask = 0;
int
md_parse_option (c, arg)
int c ATTRIBUTE_UNUSED;
char * arg ATTRIBUTE_UNUSED;
{
switch (c)
{
case OPTION_CPU_IP2022:
ip2k_mach = bfd_mach_ip2022;
ip2k_mach_bitmask = 1 << MACH_IP2022;
break;
case OPTION_CPU_IP2022EXT:
ip2k_mach = bfd_mach_ip2022ext;
ip2k_mach_bitmask = 1 << MACH_IP2022EXT;
break;
default:
return 0;
}
return 1;
}
void
md_show_usage (stream)
FILE * stream;
{
fprintf (stream, _("IP2K specific command line options:\n"));
fprintf (stream, _(" -mip2022 restrict to IP2022 insns \n"));
fprintf (stream, _(" -mip2022ext permit extended IP2022 insn\n"));
}
void
md_begin ()
{
/* Initialize the `cgen' interface. */
/* Set the machine number and endian. */
gas_cgen_cpu_desc = ip2k_cgen_cpu_open (CGEN_CPU_OPEN_MACHS,
ip2k_mach_bitmask,
CGEN_CPU_OPEN_ENDIAN,
CGEN_ENDIAN_BIG,
CGEN_CPU_OPEN_END);
ip2k_cgen_init_asm (gas_cgen_cpu_desc);
/* This is a callback from cgen to gas to parse operands. */
cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
/* Set the machine type. */
bfd_default_set_arch_mach (stdoutput, bfd_arch_ip2k, ip2k_mach);
}
void
md_assemble (str)
char * str;
{
ip2k_insn insn;
char * errmsg;
/* Initialize GAS's cgen interface for a new instruction. */
gas_cgen_init_parse ();
insn.insn = ip2k_cgen_assemble_insn
(gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
if (!insn.insn)
{
as_bad ("%s", errmsg);
return;
}
/* Check for special relocation required by SKIP instructions. */
if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SKIPA))
/* Unconditional skip has a 1-bit relocation of the current pc, so
that we emit either sb pcl.0 or snb pcl.0 depending on whether
the PCL (pc + 2) >> 1 is odd or even. */
{
enum cgen_parse_operand_result result_type;
long value;
const char *curpc_plus_2 = ".+2";
errmsg = cgen_parse_address (gas_cgen_cpu_desc, & curpc_plus_2,
IP2K_OPERAND_ADDR16CJP,
BFD_RELOC_IP2K_PC_SKIP,
& result_type, & value);
if (errmsg)
{
as_bad ("%s", errmsg);
return;
}
}
/* Doesn't really matter what we pass for RELAX_P here. */
gas_cgen_finish_insn (insn.insn, insn.buffer,
CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
}
valueT
md_section_align (segment, size)
segT segment;
valueT size;
{
int align = bfd_get_section_alignment (stdoutput, segment);
return ((size + (1 << align) - 1) & (-1 << align));
}
symbolS *
md_undefined_symbol (name)
char * name ATTRIBUTE_UNUSED;
{
return 0;
}
int
md_estimate_size_before_relax (fragP, segment)
fragS * fragP ATTRIBUTE_UNUSED;
segT segment ATTRIBUTE_UNUSED;
{
as_fatal (_("md_estimate_size_before_relax\n"));
return 1;
}
/* *fragP has been relaxed to its final size, and now needs to have
the bytes inside it modified to conform to the new size.
Called after relaxation is finished.
fragP->fr_type == rs_machine_dependent.
fragP->fr_subtype is the subtype of what the address relaxed to. */
void
md_convert_frag (abfd, sec, fragP)
bfd * abfd ATTRIBUTE_UNUSED;
segT sec ATTRIBUTE_UNUSED;
fragS * fragP ATTRIBUTE_UNUSED;
{
}
/* Functions concerning relocs. */
long
md_pcrel_from (fixP)
fixS *fixP;
{
as_fatal (_("md_pcrel_from\n"));
/* Return the address of the delay slot. */
return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
}
/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
Returns BFD_RELOC_NONE if no reloc type can be found.
*FIXP may be modified if desired. */
bfd_reloc_code_real_type
md_cgen_lookup_reloc (insn, operand, fixP)
const CGEN_INSN * insn ATTRIBUTE_UNUSED;
const CGEN_OPERAND * operand;
fixS * fixP ATTRIBUTE_UNUSED;
{
bfd_reloc_code_real_type result;
result = BFD_RELOC_NONE;
switch (operand->type)
{
case IP2K_OPERAND_FR:
case IP2K_OPERAND_ADDR16L:
case IP2K_OPERAND_ADDR16H:
case IP2K_OPERAND_LIT8:
/* These may have been processed at parse time. */
if (fixP->fx_cgen.opinfo != 0)
result = fixP->fx_cgen.opinfo;
fixP->fx_no_overflow = 1;
break;
case IP2K_OPERAND_ADDR16CJP:
result = fixP->fx_cgen.opinfo;
if (result == 0 || result == BFD_RELOC_NONE)
result = BFD_RELOC_IP2K_ADDR16CJP;
fixP->fx_no_overflow = 1;
break;
case IP2K_OPERAND_ADDR16P:
result = BFD_RELOC_IP2K_PAGE3;
fixP->fx_no_overflow = 1;
break;
default:
result = BFD_RELOC_NONE;
break;
}
return result;
}
/* Write a value out to the object file, using the appropriate endianness. */
void
md_number_to_chars (buf, val, n)
char * buf;
valueT val;
int n;
{
number_to_chars_bigendian (buf, val, n);
}
/* Turn a string in input_line_pointer into a floating point constant of type
type, and store the appropriate bytes in *litP. The number of LITTLENUMS
emitted is stored in *sizeP . An error message is returned, or NULL on
OK. */
/* Equal to MAX_PRECISION in atof-ieee.c */
#define MAX_LITTLENUMS 6
char *
md_atof (type, litP, sizeP)
char type;
char * litP;
int * sizeP;
{
int prec;
LITTLENUM_TYPE words [MAX_LITTLENUMS];
LITTLENUM_TYPE *wordP;
char * t;
char * atof_ieee PARAMS ((char *, int, LITTLENUM_TYPE *));
switch (type)
{
case 'f':
case 'F':
case 's':
case 'S':
prec = 2;
break;
case 'd':
case 'D':
case 'r':
case 'R':
prec = 4;
break;
/* FIXME: Some targets allow other format chars for bigger sizes here. */
default:
* sizeP = 0;
return _("Bad call to md_atof()");
}
t = atof_ieee (input_line_pointer, type, words);
if (t)
input_line_pointer = t;
* sizeP = prec * sizeof (LITTLENUM_TYPE);
/* This loops outputs the LITTLENUMs in REVERSE order; in accord with
the ip2k endianness. */
for (wordP = words; prec--;)
{
md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
litP += sizeof (LITTLENUM_TYPE);
}
return 0;
}
/* See whether we need to force a relocation into the output file.
Force most of them, since the linker's bfd relocation engine
understands range limits better than gas' cgen fixup engine.
Consider the case of a fixup intermediate value being larger than
the instruction it will be eventually encoded within. */
int
ip2k_force_relocation (fix)
fixS * fix;
{
switch (fix->fx_r_type)
{
/* (No C++ support in ip2k. */
/* case BFD_RELOC_VTABLE_INHERIT: */
/* case BFD_RELOC_VTABLE_ENTRY: */
case BFD_RELOC_IP2K_FR9:
case BFD_RELOC_IP2K_FR_OFFSET:
case BFD_RELOC_IP2K_BANK:
case BFD_RELOC_IP2K_ADDR16CJP:
case BFD_RELOC_IP2K_PAGE3:
case BFD_RELOC_IP2K_LO8DATA:
case BFD_RELOC_IP2K_HI8DATA:
case BFD_RELOC_IP2K_EX8DATA:
case BFD_RELOC_IP2K_LO8INSN:
case BFD_RELOC_IP2K_HI8INSN:
case BFD_RELOC_IP2K_PC_SKIP:
case BFD_RELOC_IP2K_TEXT:
return 1;
case BFD_RELOC_16:
if (fix->fx_subsy && S_IS_DEFINED (fix->fx_subsy)
&& fix->fx_addsy && S_IS_DEFINED (fix->fx_addsy)
&& (S_GET_SEGMENT (fix->fx_addsy)->flags & SEC_CODE))
{
fix->fx_r_type = BFD_RELOC_IP2K_TEXT;
return 0;
}
return 0;
default:
return 0;
}
}
void
ip2k_apply_fix3 (fixP, valueP, seg)
fixS *fixP;
valueT *valueP;
segT seg;
{
if (fixP->fx_r_type == BFD_RELOC_IP2K_TEXT
&& ! fixP->fx_addsy
&& ! fixP->fx_subsy)
{
*valueP = ((int)(*valueP)) / 2;
fixP->fx_r_type = BFD_RELOC_16;
}
else if (fixP->fx_r_type == BFD_RELOC_UNUSED + IP2K_OPERAND_FR)
{
/* Must be careful when we are fixing up an FR. We could be
fixing up an offset to (SP) or (DP) in which case we don't
want to step on the top 2 bits of the FR operand. The
gas_cgen_md_apply_fix3 doesn't know any better and overwrites
the entire operand. We counter this by adding the bits
to the new value. */
char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
/* Canonical name, since used a lot. */
CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
CGEN_INSN_INT insn_value
= cgen_get_insn_value (cd, where,
CGEN_INSN_BITSIZE (fixP->fx_cgen.insn));
/* Preserve (DP) or (SP) specification. */
*valueP += (insn_value & 0x180);
}
gas_cgen_md_apply_fix3 (fixP, valueP, seg);
}
int
ip2k_elf_section_flags (flags, attr, type)
int flags;
int attr ATTRIBUTE_UNUSED;
int type ATTRIBUTE_UNUSED;
{
/* This is used to detect when the section changes to an executable section.
This function is called by the elf section processing. When we note an
executable section specifier we set an internal flag to denote when
word alignment should be forced. */
if (flags & SEC_CODE)
force_code_align = 1;
return flags;
}
static void
ip2k_elf_section_rtn (int i)
{
obj_elf_section(i);
if (force_code_align)
{
/* The s_align_ptwo function expects that we are just after a .align
directive and it will either try and read the align value or stop
if end of line so we must fake it out so it thinks we are at the
end of the line. */
char *old_input_line_pointer = input_line_pointer;
input_line_pointer = "\n";
s_align_ptwo (1);
force_code_align = 0;
/* Restore. */
input_line_pointer = old_input_line_pointer;
}
}
static void
ip2k_elf_section_text (int i)
{
char *old_input_line_pointer;
obj_elf_text(i);
/* the s_align_ptwo function expects that we are just after a .align
directive and it will either try and read the align value or stop if
end of line so we must fake it out so it thinks we are at the end of
the line. */
old_input_line_pointer = input_line_pointer;
input_line_pointer = "\n";
s_align_ptwo (1);
force_code_align = 0;
/* Restore. */
input_line_pointer = old_input_line_pointer;
}

65
gas/config/tc-ip2k.h Normal file
View File

@ -0,0 +1,65 @@
/* tc-ip2k.h -- Header file for tc-ip2k.c.
Copyright (C) 2000, 2002 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define TC_IP2K
#ifndef BFD_ASSEMBLER
/* Leading space so will compile with cc. */
#error IP2K support requires BFD_ASSEMBLER
#endif
#define LISTING_HEADER "IP2xxx GAS "
/* The target BFD architecture. */
#define TARGET_ARCH bfd_arch_ip2k
#define TARGET_FORMAT "elf32-ip2k"
#define TARGET_BYTES_BIG_ENDIAN 1
/* Permit temporary numeric labels. */
#define LOCAL_LABELS_FB 1
/* .-foo gets turned into PC relative relocs. */
#define DIFF_EXPR_OK
/* We don't need to handle .word strangely. */
#define WORKING_DOT_WORD
#define LITERAL_PREFIXDOLLAR_HEX
#define LITERAL_PREFIXPERCENT_BIN
#define DOUBLESLASH_LINE_COMMENTS
#define MD_APPLY_FIX3
#define md_apply_fix3 ip2k_apply_fix3
#define md_elf_section_flags ip2k_elf_section_flags
extern int ip2k_elf_section_flags PARAMS ((int, int, int));
#define TC_HANDLES_FX_DONE
#define tc_gen_reloc gas_cgen_tc_gen_reloc
#define md_operand(x) gas_cgen_md_operand (x)
extern void gas_cgen_md_operand PARAMS ((expressionS *));
#define TC_FORCE_RELOCATION(fixp) ip2k_force_relocation (fixp)
extern int ip2k_force_relocation PARAMS ((struct fix *));

343
gas/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -128,6 +128,7 @@ changequote(,)dnl
i[3456]86) cpu_type=i386 arch=i386;;
x86_64) cpu_type=i386 arch=x86_64;;
ia64) cpu_type=ia64 ;;
ip2k) cpu_type=ip2k endian=big ;;
m6811|m6812|m68hc12) cpu_type=m68hc11 ;;
m680[012346]0) cpu_type=m68k ;;
changequote([,])dnl
@ -327,6 +328,8 @@ changequote([,])dnl
ia64-*-hpux*) fmt=elf em=hpux ;;
ia64-*-netbsd*) fmt=elf em=nbsd ;;
ip2k-*-*) fmt=elf bfd_gas=yes ;;
m32r-*-*) fmt=elf bfd_gas=yes ;;
m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)fmt=elf bfd_gas=yes ;;
@ -577,7 +580,7 @@ changequote([,])dnl
# Any other special object files needed ?
case ${cpu_type} in
fr30 | m32r | openrisc)
fr30 | ip2k | m32r | openrisc)
using_cgen=yes
;;

View File

@ -39,6 +39,7 @@ CPU_DOCS = \
c-i386.texi \
c-i860.texi \
c-i960.texi \
c-ip2k.texi \
c-m32r.texi \
c-m68hc11.texi \
c-m68k.texi \

View File

@ -150,6 +150,7 @@ CPU_DOCS = \
c-i386.texi \
c-i860.texi \
c-i960.texi \
c-ip2k.texi \
c-m32r.texi \
c-m68hc11.texi \
c-m68k.texi \

View File

@ -40,6 +40,7 @@
@set I80386
@set I860
@set I960
@set IP2K
@set M32R
@set M68HC11
@set M680X0

View File

@ -43,6 +43,7 @@
@set I860
@set I960
@set IA-64
@set IP2K
@set M32R
@set M68HC11
@set M680X0
@ -342,6 +343,11 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
[@b{-mle}|@b{mbe}]
[@b{-x}|@b{-xexplicit}] [@b{-xauto}] [@b{-xdebug}]
@end ifset
@ifset IP2K
@emph{Target IP2K options:}
[@b{-mip2022}|@b{-mip2022ext}]
@end ifset
@ifset M32R
@emph{Target M32R options:}
@ -670,6 +676,22 @@ error if necessary.
@end table
@end ifset
@ifset IP2K
The following options are available when @value{AS} is configured for the
Scenix IP2K series.
@table @gcctabopt
@item -mip2022ext
Specifies that the extended IP2022 instructions are allowed.
@item -mip2022
Restores the default behaviour, which restricts the permited instructions to
just the basic IP2022 ones.
@end table
@end ifset
@ifset M32R
The following options are available when @value{AS} is configured for the
Mitsubishi M32R series.
@ -1998,6 +2020,9 @@ is considered a comment and is ignored. The line comment character is
@ifset SPARC
@samp{!} on the SPARC;
@end ifset
@ifset IP2K
@samp{#} on the ip2k;
@end ifset
@ifset M32R
@samp{#} on the m32r;
@end ifset
@ -5690,6 +5715,9 @@ subject, see the hardware manufacturer's manual.
@ifset I960
* i960-Dependent:: Intel 80960 Dependent Features
@end ifset
@ifset IP2K
* IP2K-Dependent:: IP2K Dependent Features
@end ifset
@ifset M32R
* M32R-Dependent:: M32R Dependent Features
@end ifset
@ -5828,6 +5856,10 @@ family.
@include c-ia64.texi
@end ifset
@ifset IP2K
@include c-ip2k.texi
@end ifset
@ifset M32R
@include c-m32r.texi
@end ifset

46
gas/doc/c-ip2k.texi Normal file
View File

@ -0,0 +1,46 @@
@c Copyright 2002
@c Free Software Foundation, Inc.
@c This is part of the GAS manual.
@c For copying conditions, see the file as.texinfo.
@ifset GENERIC
@page
@node IP2K-Dependent
@chapter IP2K Dependent Features
@end ifset
@ifclear GENERIC
@node Machine Dependencies
@chapter IP2K Dependent Features
@end ifclear
@cindex IP2K support
@menu
* IP2K-Opts:: IP2K Options
@end menu
@node IP2K-Opts
@section IP2K Options
@cindex options, IP2K
@cindex IP2K options
The Scenix IP2K version of @code{@value{AS}} has a few machine
dependent options:
@table @code
@item -mip2022ext
@cindex @samp{-mip2022ext} option, IP2022
@cindex architecture options, IP2022
@cindex IP2K architecture options
@code{@value{AS}} can assemble the extended IP2022 instructions, but
it will only do so if this is specifically allowed via this command
line option.
@item -mip2022
@cindex @samp{-mip2022} option, IP2K
@cindex architecture options, IP2K
@cindex IP2K architecture options
This option restores the assembler's default behaviour of not
permitting the extended IP2022 instructions to be assembled.
@end table

View File

@ -1,3 +1,8 @@
2002-07-19 Denis Chertykov <denisc@overta.ru>
Matthew Green <mrg@redhat.com>
* dis-asm.h (print_insn_ip2k): Declare.
2002-07-10 Jakub Jelinek <jakub@redhat.com>
* elf/common.h (SHT_GNU_LIBLIST, DT_GNU_PRELINKED,

View File

@ -210,6 +210,7 @@ extern int print_insn_fr30 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_hppa PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_i860 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_i960 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_ip2k PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_m32r PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_m88k PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_mcore PARAMS ((bfd_vma, disassemble_info*));

View File

@ -1,3 +1,21 @@
2002-07-18 Denis Chertykov <denisc@overta.ru>
Frank Ch. Eigler <fche@redhat.com>
Alan Lehotsky <alehotsky@cygnus.com>
matthew green <mrg@redhat.com>
* configure.in: Add support for ip2k.
* configure: Regenerate.
* Makefile.am: Add support for ip2k.
* Makefile.in: Regenerate.
* disassemble.c: Add support for ip2k.
* ip2k-asm.c: New generated file.
* ip2k-desc.c: New generated file.
* ip2k-desc.h: New generated file.
* ip2k-dis.c: New generated file.
* ip2k-ibld.c: New generated file.
* ip2k-opc.c: New generated file.
* ip2k-opc.h: New generated file.
2002-07-17 David Mosberger <davidm@hpl.hp.com>
* ia64-opc-b.c (bWhc): New macro.

View File

@ -30,6 +30,7 @@ HFILES = \
h8500-opc.h \
ia64-asmtab.h \
ia64-opc.h \
ip2k-desc.h ip2k-opc.h \
m32r-desc.h m32r-opc.h \
mcore-opc.h \
openrisc-desc.h openrisc-opc.h \
@ -90,6 +91,11 @@ CFILES = \
ia64-opc.c \
ia64-gen.c \
ia64-asmtab.c \
ip2k-asm.c \
ip2k-desc.c \
ip2k-dis.c \
ip2k-ibld.c \
ip2k-opc.c \
m32r-asm.c \
m32r-desc.c \
m32r-dis.c \
@ -189,6 +195,11 @@ ALL_MACHINES = \
i960-dis.lo \
ia64-dis.lo \
ia64-opc.lo \
ip2k-asm.lo \
ip2k-desc.lo \
ip2k-dis.lo \
ip2k-ibld.lo \
ip2k-opc.lo \
m32r-asm.lo \
m32r-desc.lo \
m32r-dis.lo \
@ -312,7 +323,7 @@ uninstall_libopcodes:
rm -f $(DESTDIR)$(bfdincludedir)/dis-asm.h
CLEANFILES = \
stamp-m32r stamp-fr30 stamp-frv stamp-openrisc \
stamp-ip2k stamp-m32r stamp-fr30 stamp-frv stamp-openrisc \
stamp-xstormy16 \
libopcodes.a stamp-lib dep.sed DEP DEPA DEP1 DEP2
@ -330,12 +341,14 @@ CGENDEPS = \
cgen-asm.in cgen-dis.in cgen-ibld.in
if CGEN_MAINT
IP2K_DEPS = stamp-ip2k
M32R_DEPS = stamp-m32r
FR30_DEPS = stamp-fr30
FRV_DEPS = stamp-frv
OPENRISC_DEPS = stamp-openrisc
XSTORMY16_DEPS = stamp-xstormy16
else
IP2K_DEPS =
M32R_DEPS =
FR30_DEPS =
FRV_DEPS =
@ -351,6 +364,11 @@ run-cgen:
.PHONY: run-cgen
# For now, require developers to configure with --enable-cgen-maint.
$(srcdir)/ip2k-desc.h $(srcdir)/ip2k-desc.c $(srcdir)/ip2k-opc.h $(srcdir)/ip2k-opc.c $(srcdir)/ip2k-ibld.c $(srcdir)/ip2k-asm.c $(srcdir)/ip2k-dis.c: $(IP2K_DEPS)
@true
stamp-ip2k: $(CGENDEPS) $(CPUDIR)/ip2k.cpu $(CPUDIR)/ip2k.opc
$(MAKE) run-cgen arch=ip2k prefix=ip2k options= extrafiles=
$(srcdir)/m32r-desc.h $(srcdir)/m32r-desc.c $(srcdir)/m32r-opc.h $(srcdir)/m32r-opc.c $(srcdir)/m32r-ibld.c $(srcdir)/m32r-opinst.c $(srcdir)/m32r-asm.c $(srcdir)/m32r-dis.c: $(M32R_DEPS)
@true
stamp-m32r: $(CGENDEPS) $(CPUDIR)/m32r.cpu $(CPUDIR)/m32r.opc
@ -572,6 +590,23 @@ ia64-gen.lo: ia64-gen.c $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
ia64-opc-a.c ia64-opc-i.c ia64-opc-m.c ia64-opc-b.c \
ia64-opc-f.c ia64-opc-x.c ia64-opc-d.c
ia64-asmtab.lo: ia64-asmtab.c
ip2k-asm.lo: ip2k-asm.c sysdep.h config.h $(BFD_H) \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h ip2k-desc.h \
$(INCDIR)/opcode/cgen.h ip2k-opc.h opintl.h
ip2k-desc.lo: ip2k-desc.c sysdep.h config.h $(BFD_H) \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h ip2k-desc.h \
$(INCDIR)/opcode/cgen.h ip2k-opc.h opintl.h
ip2k-dis.lo: ip2k-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
$(BFD_H) $(INCDIR)/ansidecl.h \
$(INCDIR)/symcat.h ip2k-desc.h $(INCDIR)/opcode/cgen.h \
ip2k-opc.h opintl.h
ip2k-ibld.lo: ip2k-ibld.c sysdep.h config.h $(INCDIR)/dis-asm.h \
$(BFD_H) $(INCDIR)/ansidecl.h \
$(INCDIR)/symcat.h ip2k-desc.h $(INCDIR)/opcode/cgen.h \
ip2k-opc.h opintl.h
ip2k-opc.lo: ip2k-opc.c sysdep.h config.h $(BFD_H) \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h ip2k-desc.h \
$(INCDIR)/opcode/cgen.h ip2k-opc.h
m32r-asm.lo: m32r-asm.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(BFD_H) $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
m32r-opc.h opintl.h $(INCDIR)/xregex.h $(INCDIR)/xregex2.h \

View File

@ -140,6 +140,7 @@ HFILES = \
h8500-opc.h \
ia64-asmtab.h \
ia64-opc.h \
ip2k-desc.h ip2k-opc.h \
m32r-desc.h m32r-opc.h \
mcore-opc.h \
openrisc-desc.h openrisc-opc.h \
@ -201,6 +202,11 @@ CFILES = \
ia64-opc.c \
ia64-gen.c \
ia64-asmtab.c \
ip2k-asm.c \
ip2k-desc.c \
ip2k-dis.c \
ip2k-ibld.c \
ip2k-opc.c \
m32r-asm.c \
m32r-desc.c \
m32r-dis.c \
@ -301,6 +307,11 @@ ALL_MACHINES = \
i960-dis.lo \
ia64-dis.lo \
ia64-opc.lo \
ip2k-asm.lo \
ip2k-desc.lo \
ip2k-dis.lo \
ip2k-ibld.lo \
ip2k-opc.lo \
m32r-asm.lo \
m32r-desc.lo \
m32r-dis.lo \
@ -379,7 +390,7 @@ noinst_LIBRARIES = libopcodes.a
POTFILES = $(HFILES) $(CFILES)
CLEANFILES = \
stamp-m32r stamp-fr30 stamp-frv stamp-openrisc \
stamp-ip2k stamp-m32r stamp-fr30 stamp-frv stamp-openrisc \
stamp-xstormy16 \
libopcodes.a stamp-lib dep.sed DEP DEPA DEP1 DEP2
@ -396,6 +407,8 @@ CGENDEPS = \
$(CGENDIR)/opc-opinst.scm \
cgen-asm.in cgen-dis.in cgen-ibld.in
@CGEN_MAINT_TRUE@IP2K_DEPS = @CGEN_MAINT_TRUE@stamp-ip2k
@CGEN_MAINT_FALSE@IP2K_DEPS =
@CGEN_MAINT_TRUE@M32R_DEPS = @CGEN_MAINT_TRUE@stamp-m32r
@CGEN_MAINT_FALSE@M32R_DEPS =
@CGEN_MAINT_TRUE@FR30_DEPS = @CGEN_MAINT_TRUE@stamp-fr30
@ -434,7 +447,7 @@ acinclude.m4 aclocal.m4 config.in configure configure.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
TAR = gtar
GZIP_ENV = --best
SOURCES = libopcodes.a.c $(libopcodes_la_SOURCES)
OBJECTS = libopcodes.a.$(OBJEXT) $(libopcodes_la_OBJECTS)
@ -847,6 +860,11 @@ run-cgen:
.PHONY: run-cgen
# For now, require developers to configure with --enable-cgen-maint.
$(srcdir)/ip2k-desc.h $(srcdir)/ip2k-desc.c $(srcdir)/ip2k-opc.h $(srcdir)/ip2k-opc.c $(srcdir)/ip2k-ibld.c $(srcdir)/ip2k-asm.c $(srcdir)/ip2k-dis.c: $(IP2K_DEPS)
@true
stamp-ip2k: $(CGENDEPS) $(CPUDIR)/ip2k.cpu $(CPUDIR)/ip2k.opc
$(MAKE) run-cgen arch=ip2k prefix=ip2k options= extrafiles=
$(srcdir)/m32r-desc.h $(srcdir)/m32r-desc.c $(srcdir)/m32r-opc.h $(srcdir)/m32r-opc.c $(srcdir)/m32r-ibld.c $(srcdir)/m32r-opinst.c $(srcdir)/m32r-asm.c $(srcdir)/m32r-dis.c: $(M32R_DEPS)
@true
stamp-m32r: $(CGENDEPS) $(CPUDIR)/m32r.cpu $(CPUDIR)/m32r.opc
@ -1068,6 +1086,23 @@ ia64-gen.lo: ia64-gen.c $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
ia64-opc-a.c ia64-opc-i.c ia64-opc-m.c ia64-opc-b.c \
ia64-opc-f.c ia64-opc-x.c ia64-opc-d.c
ia64-asmtab.lo: ia64-asmtab.c
ip2k-asm.lo: ip2k-asm.c sysdep.h config.h $(BFD_H) \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h ip2k-desc.h \
$(INCDIR)/opcode/cgen.h ip2k-opc.h opintl.h
ip2k-desc.lo: ip2k-desc.c sysdep.h config.h $(BFD_H) \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h ip2k-desc.h \
$(INCDIR)/opcode/cgen.h ip2k-opc.h opintl.h
ip2k-dis.lo: ip2k-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
$(BFD_H) $(INCDIR)/ansidecl.h \
$(INCDIR)/symcat.h ip2k-desc.h $(INCDIR)/opcode/cgen.h \
ip2k-opc.h opintl.h
ip2k-ibld.lo: ip2k-ibld.c sysdep.h config.h $(INCDIR)/dis-asm.h \
$(BFD_H) $(INCDIR)/ansidecl.h \
$(INCDIR)/symcat.h ip2k-desc.h $(INCDIR)/opcode/cgen.h \
ip2k-opc.h opintl.h
ip2k-opc.lo: ip2k-opc.c sysdep.h config.h $(BFD_H) \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h ip2k-desc.h \
$(INCDIR)/opcode/cgen.h ip2k-opc.h
m32r-asm.lo: m32r-asm.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(BFD_H) $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
m32r-opc.h opintl.h $(INCDIR)/xregex.h $(INCDIR)/xregex2.h \

116
opcodes/configure vendored
View File

@ -3255,7 +3255,7 @@ EOF
fi
for ac_hdr in unistd.h
for ac_hdr in stdlib.h unistd.h sys/stat.h sys/types.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
@ -3387,11 +3387,24 @@ else
#include <fcntl.h>
#include <sys/mman.h>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_STDLIB_H
# include <stdlib.h>
#endif
#if HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
/* This mess was copied from the GNU getpagesize.h. */
#ifndef HAVE_GETPAGESIZE
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
/* Assume that all systems that can run configure have sys/param.h. */
# ifndef HAVE_SYS_PARAM_H
@ -3499,7 +3512,7 @@ main()
}
EOF
if { (eval echo configure:3503: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
if { (eval echo configure:3516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_func_mmap_fixed_mapped=yes
else
@ -3527,17 +3540,17 @@ unistd.h values.h sys/param.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:3531: checking for $ac_hdr" >&5
echo "configure:3544: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 3536 "configure"
#line 3549 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:3541: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:3554: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@ -3567,12 +3580,12 @@ done
__argz_count __argz_stringify __argz_next
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3571: checking for $ac_func" >&5
echo "configure:3584: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 3576 "configure"
#line 3589 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@ -3595,7 +3608,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:3599: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:3612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@ -3624,12 +3637,12 @@ done
for ac_func in stpcpy
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3628: checking for $ac_func" >&5
echo "configure:3641: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 3633 "configure"
#line 3646 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@ -3652,7 +3665,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:3656: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:3669: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@ -3686,19 +3699,19 @@ EOF
if test $ac_cv_header_locale_h = yes; then
echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
echo "configure:3690: checking for LC_MESSAGES" >&5
echo "configure:3703: checking for LC_MESSAGES" >&5
if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 3695 "configure"
#line 3708 "configure"
#include "confdefs.h"
#include <locale.h>
int main() {
return LC_MESSAGES
; return 0; }
EOF
if { (eval echo configure:3702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:3715: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
am_cv_val_LC_MESSAGES=yes
else
@ -3719,7 +3732,7 @@ EOF
fi
fi
echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
echo "configure:3723: checking whether NLS is requested" >&5
echo "configure:3736: checking whether NLS is requested" >&5
# Check whether --enable-nls or --disable-nls was given.
if test "${enable_nls+set}" = set; then
enableval="$enable_nls"
@ -3739,7 +3752,7 @@ fi
EOF
echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
echo "configure:3743: checking whether included gettext is requested" >&5
echo "configure:3756: checking whether included gettext is requested" >&5
# Check whether --with-included-gettext or --without-included-gettext was given.
if test "${with_included_gettext+set}" = set; then
withval="$with_included_gettext"
@ -3758,17 +3771,17 @@ fi
ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
echo "configure:3762: checking for libintl.h" >&5
echo "configure:3775: checking for libintl.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 3767 "configure"
#line 3780 "configure"
#include "confdefs.h"
#include <libintl.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:3772: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:3785: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@ -3785,19 +3798,19 @@ fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
echo "configure:3789: checking for gettext in libc" >&5
echo "configure:3802: checking for gettext in libc" >&5
if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 3794 "configure"
#line 3807 "configure"
#include "confdefs.h"
#include <libintl.h>
int main() {
return (int) gettext ("")
; return 0; }
EOF
if { (eval echo configure:3801: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:3814: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
gt_cv_func_gettext_libc=yes
else
@ -3813,7 +3826,7 @@ echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
if test "$gt_cv_func_gettext_libc" != "yes"; then
echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
echo "configure:3817: checking for bindtextdomain in -lintl" >&5
echo "configure:3830: checking for bindtextdomain in -lintl" >&5
ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -3821,7 +3834,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lintl $LIBS"
cat > conftest.$ac_ext <<EOF
#line 3825 "configure"
#line 3838 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@ -3832,7 +3845,7 @@ int main() {
bindtextdomain()
; return 0; }
EOF
if { (eval echo configure:3836: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:3849: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -3848,19 +3861,19 @@ fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
echo "configure:3852: checking for gettext in libintl" >&5
echo "configure:3865: checking for gettext in libintl" >&5
if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 3857 "configure"
#line 3870 "configure"
#include "confdefs.h"
int main() {
return (int) gettext ("")
; return 0; }
EOF
if { (eval echo configure:3864: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:3877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
gt_cv_func_gettext_libintl=yes
else
@ -3888,7 +3901,7 @@ EOF
# Extract the first word of "msgfmt", so it can be a program name with args.
set dummy msgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:3892: checking for $ac_word" >&5
echo "configure:3905: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -3922,12 +3935,12 @@ fi
for ac_func in dcgettext
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3926: checking for $ac_func" >&5
echo "configure:3939: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 3931 "configure"
#line 3944 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@ -3950,7 +3963,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:3954: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:3967: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@ -3977,7 +3990,7 @@ done
# Extract the first word of "gmsgfmt", so it can be a program name with args.
set dummy gmsgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:3981: checking for $ac_word" >&5
echo "configure:3994: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -4013,7 +4026,7 @@ fi
# Extract the first word of "xgettext", so it can be a program name with args.
set dummy xgettext; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:4017: checking for $ac_word" >&5
echo "configure:4030: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -4045,7 +4058,7 @@ else
fi
cat > conftest.$ac_ext <<EOF
#line 4049 "configure"
#line 4062 "configure"
#include "confdefs.h"
int main() {
@ -4053,7 +4066,7 @@ extern int _nl_msg_cat_cntr;
return _nl_msg_cat_cntr
; return 0; }
EOF
if { (eval echo configure:4057: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:4070: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
CATOBJEXT=.gmo
DATADIRNAME=share
@ -4085,7 +4098,7 @@ fi
# Extract the first word of "msgfmt", so it can be a program name with args.
set dummy msgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:4089: checking for $ac_word" >&5
echo "configure:4102: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -4119,7 +4132,7 @@ fi
# Extract the first word of "gmsgfmt", so it can be a program name with args.
set dummy gmsgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:4123: checking for $ac_word" >&5
echo "configure:4136: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -4155,7 +4168,7 @@ fi
# Extract the first word of "xgettext", so it can be a program name with args.
set dummy xgettext; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:4159: checking for $ac_word" >&5
echo "configure:4172: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -4245,7 +4258,7 @@ fi
LINGUAS=
else
echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
echo "configure:4249: checking for catalogs to be installed" >&5
echo "configure:4262: checking for catalogs to be installed" >&5
NEW_LINGUAS=
for lang in ${LINGUAS=$ALL_LINGUAS}; do
case "$ALL_LINGUAS" in
@ -4273,17 +4286,17 @@ echo "configure:4249: checking for catalogs to be installed" >&5
if test "$CATOBJEXT" = ".cat"; then
ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
echo "configure:4277: checking for linux/version.h" >&5
echo "configure:4290: checking for linux/version.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 4282 "configure"
#line 4295 "configure"
#include "confdefs.h"
#include <linux/version.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4287: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:4300: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@ -4361,7 +4374,7 @@ if test "x$cross_compiling" = "xno"; then
EXEEXT_FOR_BUILD='$(EXEEXT)'
else
echo $ac_n "checking for build system executable suffix""... $ac_c" 1>&6
echo "configure:4365: checking for build system executable suffix" >&5
echo "configure:4378: checking for build system executable suffix" >&5
if eval "test \"`echo '$''{'bfd_cv_build_exeext'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -4398,7 +4411,7 @@ fi
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:4402: checking for a BSD compatible install" >&5
echo "configure:4415: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -4455,17 +4468,17 @@ for ac_hdr in string.h strings.h stdlib.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:4459: checking for $ac_hdr" >&5
echo "configure:4472: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 4464 "configure"
#line 4477 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4469: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:4482: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@ -4601,6 +4614,7 @@ if test x${all_targets} = xfalse ; then
bfd_i860_arch) ta="$ta i860-dis.lo" ;;
bfd_i960_arch) ta="$ta i960-dis.lo" ;;
bfd_ia64_arch) ta="$ta ia64-dis.lo ia64-opc.lo" ;;
bfd_ip2k_arch) ta="$ta ip2k-asm.lo ip2k-desc.lo ip2k-dis.lo ip2k-ibld.lo ip2k-opc.lo" using_cgen=yes ;;
bfd_m32r_arch) ta="$ta m32r-asm.lo m32r-desc.lo m32r-dis.lo m32r-ibld.lo m32r-opc.lo m32r-opinst.lo" using_cgen=yes ;;
bfd_m68hc11_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
bfd_m68hc12_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;

View File

@ -189,6 +189,7 @@ if test x${all_targets} = xfalse ; then
bfd_i860_arch) ta="$ta i860-dis.lo" ;;
bfd_i960_arch) ta="$ta i960-dis.lo" ;;
bfd_ia64_arch) ta="$ta ia64-dis.lo ia64-opc.lo" ;;
bfd_ip2k_arch) ta="$ta ip2k-asm.lo ip2k-desc.lo ip2k-dis.lo ip2k-ibld.lo ip2k-opc.lo" using_cgen=yes ;;
bfd_m32r_arch) ta="$ta m32r-asm.lo m32r-desc.lo m32r-dis.lo m32r-ibld.lo m32r-opc.lo m32r-opinst.lo" using_cgen=yes ;;
bfd_m68hc11_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
bfd_m68hc12_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;

View File

@ -36,6 +36,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define ARCH_i386
#define ARCH_i860
#define ARCH_i960
#define ARCH_ip2k
#define ARCH_ia64
#define ARCH_fr30
#define ARCH_m32r
@ -179,6 +180,11 @@ disassembler (abfd)
disassemble = print_insn_ia64;
break;
#endif
#ifdef ARCH_ip2k
case bfd_arch_ip2k:
disassemble = print_insn_ip2k;
break;
#endif
#ifdef ARCH_fr30
case bfd_arch_fr30:
disassemble = print_insn_fr30;

977
opcodes/ip2k-asm.c Normal file
View File

@ -0,0 +1,977 @@
/* Assembler interface for targets using CGEN. -*- C -*-
CGEN: Cpu tools GENerator
THIS FILE IS MACHINE GENERATED WITH CGEN.
- the resultant file is machine generated, cgen-asm.in isn't
Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU Binutils and GDB, the GNU debugger.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
Keep that in mind. */
#include "sysdep.h"
#include <stdio.h>
#include "ansidecl.h"
#include "bfd.h"
#include "symcat.h"
#include "ip2k-desc.h"
#include "ip2k-opc.h"
#include "opintl.h"
#include "xregex.h"
#include "libiberty.h"
#include "safe-ctype.h"
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#undef max
#define max(a,b) ((a) > (b) ? (a) : (b))
static const char * parse_insn_normal
PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *));
/* -- assembler routines inserted here. */
/* -- asm.c */
static const char *
parse_fr (cd, strp, opindex, valuep)
CGEN_CPU_DESC cd;
const char **strp;
int opindex;
long *valuep;
{
const char *errmsg;
char *old_strp;
char *afteroffset;
enum cgen_parse_operand_result result_type;
bfd_vma value;
extern CGEN_KEYWORD ip2k_cgen_opval_register_names;
long tempvalue;
old_strp = *strp;
afteroffset = NULL;
/* Check here to see if you're about to try parsing a w as the first arg */
/* and return an error if you are. */
if ( (strncmp(*strp,"w",1)==0) || (strncmp(*strp,"W",1)==0) )
{
(*strp)++;
if ( (strncmp(*strp,",",1)==0) || isspace(**strp) )
{
/* We've been passed a w. Return with an error message so that */
/* cgen will try the next parsing option. */
errmsg = _("W keyword invalid in FR operand slot.");
return errmsg;
}
*strp = old_strp;
}
/* Attempt parse as register keyword. */
/* old_strp = *strp; */
errmsg = cgen_parse_keyword (cd, strp, & ip2k_cgen_opval_register_names, valuep);
if ( *strp != NULL )
if (errmsg == NULL)
return errmsg;
/* Attempt to parse for "(IP)" */
afteroffset = strstr(*strp,"(IP)");
if ( afteroffset == NULL)
{
/* Make sure it's not in lower case */
afteroffset = strstr(*strp,"(ip)");
}
if ( afteroffset != NULL )
{
if ( afteroffset != *strp )
{
/* Invalid offset present.*/
errmsg = _("offset(IP) is not a valid form");
return errmsg;
}
else
{
*strp += 4;
*valuep = 0;
errmsg = NULL;
return errmsg;
}
}
/* Attempt to parse for DP. ex: mov w, offset(DP) */
/* mov offset(DP),w */
/* Try parsing it as an address and see what comes back */
afteroffset = strstr(*strp,"(DP)");
if ( afteroffset == NULL)
{
/* Maybe it's in lower case */
afteroffset = strstr(*strp,"(dp)");
}
if ( afteroffset != NULL )
{
if ( afteroffset == *strp )
{
/* No offset present. Use 0 by default. */
tempvalue = 0;
errmsg = NULL;
}
else
{
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IP2K_FR_OFFSET,
& result_type, & tempvalue);
}
if (errmsg == NULL)
{
if ( (tempvalue >= 0) && (tempvalue <= 127) )
{
/* Value is ok. Fix up the first 2 bits and return */
*valuep = 0x0100 | tempvalue;
*strp += 4; /* skip over the (DP) in *strp */
return errmsg;
} else
{
/* Found something there in front of (DP) but it's out of range. */
errmsg = _("(DP) offset out of range.");
return errmsg;
}
}
}
/* Attempt to parse for SP. ex: mov w, offset(SP) */
/* mov offset(SP), w */
afteroffset = strstr(*strp,"(SP)");
if (afteroffset == NULL)
{
/* Maybe it's in lower case. */
afteroffset = strstr(*strp, "(sp)");
}
if ( afteroffset != NULL )
{
if ( afteroffset == *strp )
{
/* No offset present. Use 0 by default. */
tempvalue = 0;
errmsg = NULL;
}
else
{
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IP2K_FR_OFFSET,
& result_type, & tempvalue);
}
if (errmsg == NULL)
{
if ( (tempvalue >= 0) && (tempvalue <= 127) )
{
/* Value is ok. Fix up the first 2 bits and return */
*valuep = 0x0180 | tempvalue;
*strp += 4; /* skip over the (SP) in *strp */
return errmsg;
} else
{
/* Found something there in front of (SP) but it's out of range. */
errmsg = _("(SP) offset out of range.");
return errmsg;
}
}
}
/* Attempt to parse as an address. */
*strp = old_strp;
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IP2K_FR9,
& result_type, & value);
if (errmsg == NULL)
{
*valuep = value;
/* if a parenthesis is found, warn about invalid form */
if (**strp == '(')
{
errmsg = _("illegal use of parentheses");
}
/* if a numeric value is specified, ensure that it is between 1 and 255 */
else if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
{
if (value < 0x1 || value > 0xff)
errmsg = _("operand out of range (not between 1 and 255)");
}
}
return errmsg;
}
static const char *
parse_addr16 (cd, strp, opindex, valuep)
CGEN_CPU_DESC cd;
const char **strp;
int opindex;
long *valuep;
{
const char *errmsg;
enum cgen_parse_operand_result result_type;
bfd_reloc_code_real_type code = BFD_RELOC_NONE;
long value;
if ( opindex == (CGEN_OPERAND_TYPE)IP2K_OPERAND_ADDR16H )
code = BFD_RELOC_IP2K_HI8DATA;
else if ( opindex == (CGEN_OPERAND_TYPE)IP2K_OPERAND_ADDR16L )
code = BFD_RELOC_IP2K_LO8DATA;
else
{
/* Something is very wrong. opindex has to be one of the above. */
errmsg = _("parse_addr16: invalid opindex.");
return errmsg;
}
errmsg = cgen_parse_address (cd, strp, opindex, code,
& result_type, & value);
if (errmsg == NULL)
{
/* We either have a relocation or a number now. */
if ( result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER )
{
/* We got a number back. */
if ( code == BFD_RELOC_IP2K_HI8DATA )
value >>= 8;
else /* code = BFD_RELOC_IP2K_LOW8DATA */
value &= 0x00FF;
}
*valuep = value;
}
return errmsg;
}
static const char *
parse_addr16_p (cd, strp, opindex, valuep)
CGEN_CPU_DESC cd;
const char **strp;
int opindex;
long *valuep;
{
const char *errmsg;
enum cgen_parse_operand_result result_type;
bfd_reloc_code_real_type code = BFD_RELOC_IP2K_PAGE3;
long value;
errmsg = cgen_parse_address (cd, strp, opindex, code,
& result_type, & value);
if (errmsg == NULL)
{
if ( result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER )
*valuep = (value >> 13) & 0x7;
else if ( result_type == CGEN_PARSE_OPERAND_RESULT_QUEUED )
*valuep = value;
}
return errmsg;
}
static const char *
parse_addr16_cjp (cd, strp, opindex, valuep)
CGEN_CPU_DESC cd;
const char **strp;
int opindex;
long *valuep;
{
const char *errmsg;
enum cgen_parse_operand_result result_type;
bfd_reloc_code_real_type code = BFD_RELOC_NONE;
long value;
if ( opindex == (CGEN_OPERAND_TYPE)IP2K_OPERAND_ADDR16CJP )
code = BFD_RELOC_IP2K_ADDR16CJP;
else if ( opindex == (CGEN_OPERAND_TYPE)IP2K_OPERAND_ADDR16P )
code = BFD_RELOC_IP2K_PAGE3;
errmsg = cgen_parse_address (cd, strp, opindex, code,
& result_type, & value);
if (errmsg == NULL)
{
if ( result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER )
{
if ( (value & 0x1) == 0) /* If the address is even .... */
{
if ( opindex == (CGEN_OPERAND_TYPE)IP2K_OPERAND_ADDR16CJP )
*valuep = (value >> 1) & 0x1FFF; /* Should mask be 1FFF? */
else if ( opindex == (CGEN_OPERAND_TYPE)IP2K_OPERAND_ADDR16P )
*valuep = (value >> 14) & 0x7;
}
else
errmsg = _("Byte address required. - must be even.");
}else if ( result_type == CGEN_PARSE_OPERAND_RESULT_QUEUED )
{
/* This will happen for things like (s2-s1) where s2 and s1 */
/* are labels. */
*valuep = value;
}
else
errmsg = _("cgen_parse_address returned a symbol. Literal required.");
}
return errmsg;
}
static const char *
parse_lit8 (cd, strp, opindex, valuep)
CGEN_CPU_DESC cd;
const char **strp;
int opindex;
long *valuep;
{
const char *errmsg;
enum cgen_parse_operand_result result_type;
bfd_reloc_code_real_type code = BFD_RELOC_NONE;
long value;
/* Parse %OP relocating operators. */
if (strncmp (*strp, "%bank", 5) == 0)
{
*strp += 5;
code = BFD_RELOC_IP2K_BANK;
}
else if (strncmp (*strp, "%lo8data", 8) == 0)
{
*strp += 8;
code = BFD_RELOC_IP2K_LO8DATA;
}
else if (strncmp (*strp, "%hi8data", 8) == 0)
{
*strp += 8;
code = BFD_RELOC_IP2K_HI8DATA;
}
else if (strncmp (*strp, "%ex8data", 8) == 0)
{
*strp += 8;
code = BFD_RELOC_IP2K_EX8DATA;
}
else if (strncmp (*strp, "%lo8insn", 8) == 0)
{
*strp += 8;
code = BFD_RELOC_IP2K_LO8INSN;
}
else if (strncmp (*strp, "%hi8insn", 8) == 0)
{
*strp += 8;
code = BFD_RELOC_IP2K_HI8INSN;
}
/* Parse %op operand. */
if (code != BFD_RELOC_NONE)
{
errmsg = cgen_parse_address (cd, strp, opindex, code,
& result_type, & value);
if ((errmsg == NULL) &&
(result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED))
errmsg = _("%operator operand is not a symbol");
*valuep = value;
}
/* Parse as a number. */
else
{
errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
/* Truncate to eight bits to accept both signed and unsigned input. */
if (errmsg == NULL)
*valuep &= 0xFF;
}
return errmsg;
}
static const char *
parse_bit3 (cd, strp, opindex, valuep)
CGEN_CPU_DESC cd;
const char **strp;
int opindex;
long *valuep;
{
const char *errmsg;
char mode = 0;
long count = 0;
unsigned long value;
if (strncmp (*strp, "%bit", 4) == 0)
{
*strp += 4;
mode = 1;
}
else if (strncmp (*strp, "%msbbit", 7) == 0)
{
*strp += 7;
mode = 1;
}
else if (strncmp (*strp, "%lsbbit", 7) == 0)
{
*strp += 7;
mode = 2;
}
errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
if (errmsg) {
return errmsg;
}
if (mode) {
value = (unsigned long) *valuep;
if (value == 0) {
errmsg = _("Attempt to find bit index of 0");
return errmsg;
}
if (mode == 1) {
count = 31;
while ((value & 0x80000000) == 0) {
count--;
value <<= 1;
}
} else if (mode == 2) {
count = 0;
while ((value & 0x00000001) == 0) {
count++;
value >>= 1;
}
}
*valuep = count;
}
return errmsg;
}
/* -- dis.c */
const char * ip2k_cgen_parse_operand
PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *));
/* Main entry point for operand parsing.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `parse_insn_normal', but keeping it
separate makes clear the interface between `parse_insn_normal' and each of
the handlers. */
const char *
ip2k_cgen_parse_operand (cd, opindex, strp, fields)
CGEN_CPU_DESC cd;
int opindex;
const char ** strp;
CGEN_FIELDS * fields;
{
const char * errmsg = NULL;
/* Used by scalar operands that still need to be parsed. */
long junk ATTRIBUTE_UNUSED;
switch (opindex)
{
case IP2K_OPERAND_ADDR16CJP :
errmsg = parse_addr16_cjp (cd, strp, IP2K_OPERAND_ADDR16CJP, &fields->f_addr16cjp);
break;
case IP2K_OPERAND_ADDR16H :
errmsg = parse_addr16 (cd, strp, IP2K_OPERAND_ADDR16H, &fields->f_imm8);
break;
case IP2K_OPERAND_ADDR16L :
errmsg = parse_addr16 (cd, strp, IP2K_OPERAND_ADDR16L, &fields->f_imm8);
break;
case IP2K_OPERAND_ADDR16P :
errmsg = parse_addr16_cjp (cd, strp, IP2K_OPERAND_ADDR16P, &fields->f_page3);
break;
case IP2K_OPERAND_BITNO :
errmsg = parse_bit3 (cd, strp, IP2K_OPERAND_BITNO, &fields->f_bitno);
break;
case IP2K_OPERAND_CBIT :
errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_CBIT, &junk);
break;
case IP2K_OPERAND_DCBIT :
errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_DCBIT, &junk);
break;
case IP2K_OPERAND_FR :
errmsg = parse_fr (cd, strp, IP2K_OPERAND_FR, &fields->f_reg);
break;
case IP2K_OPERAND_LIT8 :
errmsg = parse_lit8 (cd, strp, IP2K_OPERAND_LIT8, &fields->f_imm8);
break;
case IP2K_OPERAND_PABITS :
errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_PABITS, &junk);
break;
case IP2K_OPERAND_RETI3 :
errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_RETI3, &fields->f_reti3);
break;
case IP2K_OPERAND_ZBIT :
errmsg = cgen_parse_unsigned_integer (cd, strp, IP2K_OPERAND_ZBIT, &junk);
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
abort ();
}
return errmsg;
}
cgen_parse_fn * const ip2k_cgen_parse_handlers[] =
{
parse_insn_normal,
};
void
ip2k_cgen_init_asm (cd)
CGEN_CPU_DESC cd;
{
ip2k_cgen_init_opcode_table (cd);
ip2k_cgen_init_ibld_table (cd);
cd->parse_handlers = & ip2k_cgen_parse_handlers[0];
cd->parse_operand = ip2k_cgen_parse_operand;
}
/* Regex construction routine.
This translates an opcode syntax string into a regex string,
by replacing any non-character syntax element (such as an
opcode) with the pattern '.*'
It then compiles the regex and stores it in the opcode, for
later use by ip2k_cgen_assemble_insn
Returns NULL for success, an error message for failure. */
char *
ip2k_cgen_build_insn_regex (insn)
CGEN_INSN *insn;
{
CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
const char *mnem = CGEN_INSN_MNEMONIC (insn);
char rxbuf[CGEN_MAX_RX_ELEMENTS];
char *rx = rxbuf;
const CGEN_SYNTAX_CHAR_TYPE *syn;
int reg_err;
syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
/* Mnemonics come first in the syntax string. */
if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
return _("missing mnemonic in syntax string");
++syn;
/* Generate a case sensitive regular expression that emulates case
insensitive matching in the "C" locale. We cannot generate a case
insensitive regular expression because in Turkish locales, 'i' and 'I'
are not equal modulo case conversion. */
/* Copy the literal mnemonic out of the insn. */
for (; *mnem; mnem++)
{
char c = *mnem;
if (ISALPHA (c))
{
*rx++ = '[';
*rx++ = TOLOWER (c);
*rx++ = TOUPPER (c);
*rx++ = ']';
}
else
*rx++ = c;
}
/* Copy any remaining literals from the syntax string into the rx. */
for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
{
if (CGEN_SYNTAX_CHAR_P (* syn))
{
char c = CGEN_SYNTAX_CHAR (* syn);
switch (c)
{
/* Escape any regex metacharacters in the syntax. */
case '.': case '[': case '\\':
case '*': case '^': case '$':
#ifdef CGEN_ESCAPE_EXTENDED_REGEX
case '?': case '{': case '}':
case '(': case ')': case '*':
case '|': case '+': case ']':
#endif
*rx++ = '\\';
*rx++ = c;
break;
default:
if (ISALPHA (c))
{
*rx++ = '[';
*rx++ = TOLOWER (c);
*rx++ = TOUPPER (c);
*rx++ = ']';
}
else
*rx++ = c;
break;
}
}
else
{
/* Replace non-syntax fields with globs. */
*rx++ = '.';
*rx++ = '*';
}
}
/* Trailing whitespace ok. */
* rx++ = '[';
* rx++ = ' ';
* rx++ = '\t';
* rx++ = ']';
* rx++ = '*';
/* But anchor it after that. */
* rx++ = '$';
* rx = '\0';
CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
if (reg_err == 0)
return NULL;
else
{
static char msg[80];
regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
regfree ((regex_t *) CGEN_INSN_RX (insn));
free (CGEN_INSN_RX (insn));
(CGEN_INSN_RX (insn)) = NULL;
return msg;
}
}
/* Default insn parser.
The syntax string is scanned and operands are parsed and stored in FIELDS.
Relocs are queued as we go via other callbacks.
??? Note that this is currently an all-or-nothing parser. If we fail to
parse the instruction, we return 0 and the caller will start over from
the beginning. Backtracking will be necessary in parsing subexpressions,
but that can be handled there. Not handling backtracking here may get
expensive in the case of the m68k. Deal with later.
Returns NULL for success, an error message for failure. */
static const char *
parse_insn_normal (cd, insn, strp, fields)
CGEN_CPU_DESC cd;
const CGEN_INSN *insn;
const char **strp;
CGEN_FIELDS *fields;
{
/* ??? Runtime added insns not handled yet. */
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
const char *str = *strp;
const char *errmsg;
const char *p;
const CGEN_SYNTAX_CHAR_TYPE * syn;
#ifdef CGEN_MNEMONIC_OPERANDS
/* FIXME: wip */
int past_opcode_p;
#endif
/* For now we assume the mnemonic is first (there are no leading operands).
We can parse it without needing to set up operand parsing.
GAS's input scrubber will ensure mnemonics are lowercase, but we may
not be called from GAS. */
p = CGEN_INSN_MNEMONIC (insn);
while (*p && TOLOWER (*p) == TOLOWER (*str))
++p, ++str;
if (* p)
return _("unrecognized instruction");
#ifndef CGEN_MNEMONIC_OPERANDS
if (* str && ! ISSPACE (* str))
return _("unrecognized instruction");
#endif
CGEN_INIT_PARSE (cd);
cgen_init_parse_operand (cd);
#ifdef CGEN_MNEMONIC_OPERANDS
past_opcode_p = 0;
#endif
/* We don't check for (*str != '\0') here because we want to parse
any trailing fake arguments in the syntax string. */
syn = CGEN_SYNTAX_STRING (syntax);
/* Mnemonics come first for now, ensure valid string. */
if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
abort ();
++syn;
while (* syn != 0)
{
/* Non operand chars must match exactly. */
if (CGEN_SYNTAX_CHAR_P (* syn))
{
/* FIXME: While we allow for non-GAS callers above, we assume the
first char after the mnemonic part is a space. */
/* FIXME: We also take inappropriate advantage of the fact that
GAS's input scrubber will remove extraneous blanks. */
if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
{
#ifdef CGEN_MNEMONIC_OPERANDS
if (CGEN_SYNTAX_CHAR(* syn) == ' ')
past_opcode_p = 1;
#endif
++ syn;
++ str;
}
else if (*str)
{
/* Syntax char didn't match. Can't be this insn. */
static char msg [80];
/* xgettext:c-format */
sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
CGEN_SYNTAX_CHAR(*syn), *str);
return msg;
}
else
{
/* Ran out of input. */
static char msg [80];
/* xgettext:c-format */
sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
CGEN_SYNTAX_CHAR(*syn));
return msg;
}
continue;
}
/* We have an operand of some sort. */
errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
&str, fields);
if (errmsg)
return errmsg;
/* Done with this operand, continue with next one. */
++ syn;
}
/* If we're at the end of the syntax string, we're done. */
if (* syn == 0)
{
/* FIXME: For the moment we assume a valid `str' can only contain
blanks now. IE: We needn't try again with a longer version of
the insn and it is assumed that longer versions of insns appear
before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
while (ISSPACE (* str))
++ str;
if (* str != '\0')
return _("junk at end of line"); /* FIXME: would like to include `str' */
return NULL;
}
/* We couldn't parse it. */
return _("unrecognized instruction");
}
/* Main entry point.
This routine is called for each instruction to be assembled.
STR points to the insn to be assembled.
We assume all necessary tables have been initialized.
The assembled instruction, less any fixups, is stored in BUF.
Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
still needs to be converted to target byte order, otherwise BUF is an array
of bytes in target byte order.
The result is a pointer to the insn's entry in the opcode table,
or NULL if an error occured (an error message will have already been
printed).
Note that when processing (non-alias) macro-insns,
this function recurses.
??? It's possible to make this cpu-independent.
One would have to deal with a few minor things.
At this point in time doing so would be more of a curiosity than useful
[for example this file isn't _that_ big], but keeping the possibility in
mind helps keep the design clean. */
const CGEN_INSN *
ip2k_cgen_assemble_insn (cd, str, fields, buf, errmsg)
CGEN_CPU_DESC cd;
const char *str;
CGEN_FIELDS *fields;
CGEN_INSN_BYTES_PTR buf;
char **errmsg;
{
const char *start;
CGEN_INSN_LIST *ilist;
const char *parse_errmsg = NULL;
const char *insert_errmsg = NULL;
int recognized_mnemonic = 0;
/* Skip leading white space. */
while (ISSPACE (* str))
++ str;
/* The instructions are stored in hashed lists.
Get the first in the list. */
ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
/* Keep looking until we find a match. */
start = str;
for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
{
const CGEN_INSN *insn = ilist->insn;
recognized_mnemonic = 1;
#ifdef CGEN_VALIDATE_INSN_SUPPORTED
/* Not usually needed as unsupported opcodes
shouldn't be in the hash lists. */
/* Is this insn supported by the selected cpu? */
if (! ip2k_cgen_insn_supported (cd, insn))
continue;
#endif
/* If the RELAX attribute is set, this is an insn that shouldn't be
chosen immediately. Instead, it is used during assembler/linker
relaxation if possible. */
if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX) != 0)
continue;
str = start;
/* Skip this insn if str doesn't look right lexically. */
if (CGEN_INSN_RX (insn) != NULL &&
regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
continue;
/* Allow parse/insert handlers to obtain length of insn. */
CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
if (parse_errmsg != NULL)
continue;
/* ??? 0 is passed for `pc'. */
insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
(bfd_vma) 0);
if (insert_errmsg != NULL)
continue;
/* It is up to the caller to actually output the insn and any
queued relocs. */
return insn;
}
{
static char errbuf[150];
#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
const char *tmp_errmsg;
/* If requesting verbose error messages, use insert_errmsg.
Failing that, use parse_errmsg. */
tmp_errmsg = (insert_errmsg ? insert_errmsg :
parse_errmsg ? parse_errmsg :
recognized_mnemonic ?
_("unrecognized form of instruction") :
_("unrecognized instruction"));
if (strlen (start) > 50)
/* xgettext:c-format */
sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
else
/* xgettext:c-format */
sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
#else
if (strlen (start) > 50)
/* xgettext:c-format */
sprintf (errbuf, _("bad instruction `%.50s...'"), start);
else
/* xgettext:c-format */
sprintf (errbuf, _("bad instruction `%.50s'"), start);
#endif
*errmsg = errbuf;
return NULL;
}
}
#if 0 /* This calls back to GAS which we can't do without care. */
/* Record each member of OPVALS in the assembler's symbol table.
This lets GAS parse registers for us.
??? Interesting idea but not currently used. */
/* Record each member of OPVALS in the assembler's symbol table.
FIXME: Not currently used. */
void
ip2k_cgen_asm_hash_keywords (cd, opvals)
CGEN_CPU_DESC cd;
CGEN_KEYWORD *opvals;
{
CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
const CGEN_KEYWORD_ENTRY * ke;
while ((ke = cgen_keyword_search_next (& search)) != NULL)
{
#if 0 /* Unnecessary, should be done in the search routine. */
if (! ip2k_cgen_opval_supported (ke))
continue;
#endif
cgen_asm_record_register (cd, ke->name, ke->value);
}
}
#endif /* 0 */

1219
opcodes/ip2k-desc.c Normal file

File diff suppressed because it is too large Load Diff

251
opcodes/ip2k-desc.h Normal file
View File

@ -0,0 +1,251 @@
/* CPU data header for ip2k.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef IP2K_CPU_H
#define IP2K_CPU_H
#define CGEN_ARCH ip2k
/* Given symbol S, return ip2k_cgen_<S>. */
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define CGEN_SYM(s) ip2k##_cgen_##s
#else
#define CGEN_SYM(s) ip2k/**/_cgen_/**/s
#endif
/* Selected cpu families. */
#define HAVE_CPU_IP2KBF
#define CGEN_INSN_LSB0_P 1
/* Minimum size of any insn (in bytes). */
#define CGEN_MIN_INSN_SIZE 2
/* Maximum size of any insn (in bytes). */
#define CGEN_MAX_INSN_SIZE 2
#define CGEN_INT_INSN_P 1
/* Maximum number of syntax elements in an instruction. */
#define CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS 12
/* CGEN_MNEMONIC_OPERANDS is defined if mnemonics have operands.
e.g. In "b,a foo" the ",a" is an operand. If mnemonics have operands
we can't hash on everything up to the space. */
#define CGEN_MNEMONIC_OPERANDS
/* Maximum number of fields in an instruction. */
#define CGEN_ACTUAL_MAX_IFMT_OPERANDS 3
/* Enums. */
/* Enum declaration for op6 enums. */
typedef enum insn_op6 {
OP6_OTHER1, OP6_OTHER2, OP6_SUB, OP6_DEC
, OP6_OR, OP6_AND, OP6_XOR, OP6_ADD
, OP6_TEST, OP6_NOT, OP6_INC, OP6_DECSZ
, OP6_RR, OP6_RL, OP6_SWAP, OP6_INCSZ
, OP6_CSE, OP6_POP, OP6_SUBC, OP6_DECSNZ
, OP6_MULU, OP6_MULS, OP6_INCSNZ, OP6_ADDC
} INSN_OP6;
/* Enum declaration for dir enums. */
typedef enum insn_dir {
DIR_TO_W, DIR_NOTTO_W
} INSN_DIR;
/* Enum declaration for op4 enums. */
typedef enum insn_op4 {
OP4_LITERAL = 7, OP4_CLRB = 8, OP4_SETB = 9, OP4_SNB = 10
, OP4_SB = 11
} INSN_OP4;
/* Enum declaration for op4mid enums. */
typedef enum insn_op4mid {
OP4MID_LOADH_L = 0, OP4MID_LOADL_L = 1, OP4MID_MULU_L = 2, OP4MID_MULS_L = 3
, OP4MID_PUSH_L = 4, OP4MID_CSNE_L = 6, OP4MID_CSE_L = 7, OP4MID_RETW_L = 8
, OP4MID_CMP_L = 9, OP4MID_SUB_L = 10, OP4MID_ADD_L = 11, OP4MID_MOV_L = 12
, OP4MID_OR_L = 13, OP4MID_AND_L = 14, OP4MID_XOR_L = 15
} INSN_OP4MID;
/* Enum declaration for op3 enums. */
typedef enum insn_op3 {
OP3_CALL = 6, OP3_JMP = 7
} INSN_OP3;
/* Enum declaration for . */
typedef enum register_names {
H_REGISTERS_ADDRSEL = 2, H_REGISTERS_ADDRX = 3, H_REGISTERS_IPH = 4, H_REGISTERS_IPL = 5
, H_REGISTERS_SPH = 6, H_REGISTERS_SPL = 7, H_REGISTERS_PCH = 8, H_REGISTERS_PCL = 9
, H_REGISTERS_WREG = 10, H_REGISTERS_STATUS = 11, H_REGISTERS_DPH = 12, H_REGISTERS_DPL = 13
, H_REGISTERS_SPDREG = 14, H_REGISTERS_MULH = 15, H_REGISTERS_ADDRH = 16, H_REGISTERS_ADDRL = 17
, H_REGISTERS_DATAH = 18, H_REGISTERS_DATAL = 19, H_REGISTERS_INTVECH = 20, H_REGISTERS_INTVECL = 21
, H_REGISTERS_INTSPD = 22, H_REGISTERS_INTF = 23, H_REGISTERS_INTE = 24, H_REGISTERS_INTED = 25
, H_REGISTERS_FCFG = 26, H_REGISTERS_TCTRL = 27, H_REGISTERS_XCFG = 28, H_REGISTERS_EMCFG = 29
, H_REGISTERS_IPCH = 30, H_REGISTERS_IPCL = 31, H_REGISTERS_RAIN = 32, H_REGISTERS_RAOUT = 33
, H_REGISTERS_RADIR = 34, H_REGISTERS_LFSRH = 35, H_REGISTERS_RBIN = 36, H_REGISTERS_RBOUT = 37
, H_REGISTERS_RBDIR = 38, H_REGISTERS_LFSRL = 39, H_REGISTERS_RCIN = 40, H_REGISTERS_RCOUT = 41
, H_REGISTERS_RCDIR = 42, H_REGISTERS_LFSRA = 43, H_REGISTERS_RDIN = 44, H_REGISTERS_RDOUT = 45
, H_REGISTERS_RDDIR = 46, H_REGISTERS_REIN = 48, H_REGISTERS_REOUT = 49, H_REGISTERS_REDIR = 50
, H_REGISTERS_RFIN = 52, H_REGISTERS_RFOUT = 53, H_REGISTERS_RFDIR = 54, H_REGISTERS_RGOUT = 57
, H_REGISTERS_RGDIR = 58, H_REGISTERS_RTTMR = 64, H_REGISTERS_RTCFG = 65, H_REGISTERS_T0TMR = 66
, H_REGISTERS_T0CFG = 67, H_REGISTERS_T1CNTH = 68, H_REGISTERS_T1CNTL = 69, H_REGISTERS_T1CAP1H = 70
, H_REGISTERS_T1CAP1L = 71, H_REGISTERS_T1CAP2H = 72, H_REGISTERS_T1CMP2H = 72, H_REGISTERS_T1CAP2L = 73
, H_REGISTERS_T1CMP2L = 73, H_REGISTERS_T1CMP1H = 74, H_REGISTERS_T1CMP1L = 75, H_REGISTERS_T1CFG1H = 76
, H_REGISTERS_T1CFG1L = 77, H_REGISTERS_T1CFG2H = 78, H_REGISTERS_T1CFG2L = 79, H_REGISTERS_ADCH = 80
, H_REGISTERS_ADCL = 81, H_REGISTERS_ADCCFG = 82, H_REGISTERS_ADCTMR = 83, H_REGISTERS_T2CNTH = 84
, H_REGISTERS_T2CNTL = 85, H_REGISTERS_T2CAP1H = 86, H_REGISTERS_T2CAP1L = 87, H_REGISTERS_T2CAP2H = 88
, H_REGISTERS_T2CMP2H = 88, H_REGISTERS_T2CAP2L = 89, H_REGISTERS_T2CMP2L = 89, H_REGISTERS_T2CMP1H = 90
, H_REGISTERS_T2CMP1L = 91, H_REGISTERS_T2CFG1H = 92, H_REGISTERS_T2CFG1L = 93, H_REGISTERS_T2CFG2H = 94
, H_REGISTERS_T2CFG2L = 95, H_REGISTERS_S1TMRH = 96, H_REGISTERS_S1TMRL = 97, H_REGISTERS_S1TBUFH = 98
, H_REGISTERS_S1TBUFL = 99, H_REGISTERS_S1TCFG = 100, H_REGISTERS_S1RCNT = 101, H_REGISTERS_S1RBUFH = 102
, H_REGISTERS_S1RBUFL = 103, H_REGISTERS_S1RCFG = 104, H_REGISTERS_S1RSYNC = 105, H_REGISTERS_S1INTF = 106
, H_REGISTERS_S1INTE = 107, H_REGISTERS_S1MODE = 108, H_REGISTERS_S1SMASK = 109, H_REGISTERS_PSPCFG = 110
, H_REGISTERS_CMPCFG = 111, H_REGISTERS_S2TMRH = 112, H_REGISTERS_S2TMRL = 113, H_REGISTERS_S2TBUFH = 114
, H_REGISTERS_S2TBUFL = 115, H_REGISTERS_S2TCFG = 116, H_REGISTERS_S2RCNT = 117, H_REGISTERS_S2RBUFH = 118
, H_REGISTERS_S2RBUFL = 119, H_REGISTERS_S2RCFG = 120, H_REGISTERS_S2RSYNC = 121, H_REGISTERS_S2INTF = 122
, H_REGISTERS_S2INTE = 123, H_REGISTERS_S2MODE = 124, H_REGISTERS_S2SMASK = 125, H_REGISTERS_CALLH = 126
, H_REGISTERS_CALLL = 127
} REGISTER_NAMES;
/* Attributes. */
/* Enum declaration for machine type selection. */
typedef enum mach_attr {
MACH_BASE, MACH_IP2022, MACH_IP2022EXT, MACH_MAX
} MACH_ATTR;
/* Enum declaration for instruction set selection. */
typedef enum isa_attr {
ISA_IP2K, ISA_MAX
} ISA_ATTR;
/* Number of architecture variants. */
#define MAX_ISAS 1
#define MAX_MACHS ((int) MACH_MAX)
/* Ifield support. */
extern const struct cgen_ifld ip2k_cgen_ifld_table[];
/* Ifield attribute indices. */
/* Enum declaration for cgen_ifld attrs. */
typedef enum cgen_ifld_attr {
CGEN_IFLD_VIRTUAL, CGEN_IFLD_PCREL_ADDR, CGEN_IFLD_ABS_ADDR, CGEN_IFLD_RESERVED
, CGEN_IFLD_SIGN_OPT, CGEN_IFLD_SIGNED, CGEN_IFLD_END_BOOLS, CGEN_IFLD_START_NBOOLS = 31
, CGEN_IFLD_MACH, CGEN_IFLD_END_NBOOLS
} CGEN_IFLD_ATTR;
/* Number of non-boolean elements in cgen_ifld_attr. */
#define CGEN_IFLD_NBOOL_ATTRS (CGEN_IFLD_END_NBOOLS - CGEN_IFLD_START_NBOOLS - 1)
/* Enum declaration for ip2k ifield types. */
typedef enum ifield_type {
IP2K_F_NIL, IP2K_F_ANYOF, IP2K_F_IMM8, IP2K_F_REG
, IP2K_F_ADDR16CJP, IP2K_F_DIR, IP2K_F_BITNO, IP2K_F_OP3
, IP2K_F_OP4, IP2K_F_OP4MID, IP2K_F_OP6, IP2K_F_OP8
, IP2K_F_OP6_10LOW, IP2K_F_OP6_7LOW, IP2K_F_RETI3, IP2K_F_SKIPB
, IP2K_F_PAGE3, IP2K_F_MAX
} IFIELD_TYPE;
#define MAX_IFLD ((int) IP2K_F_MAX)
/* Hardware attribute indices. */
/* Enum declaration for cgen_hw attrs. */
typedef enum cgen_hw_attr {
CGEN_HW_VIRTUAL, CGEN_HW_CACHE_ADDR, CGEN_HW_PC, CGEN_HW_PROFILE
, CGEN_HW_END_BOOLS, CGEN_HW_START_NBOOLS = 31, CGEN_HW_MACH, CGEN_HW_END_NBOOLS
} CGEN_HW_ATTR;
/* Number of non-boolean elements in cgen_hw_attr. */
#define CGEN_HW_NBOOL_ATTRS (CGEN_HW_END_NBOOLS - CGEN_HW_START_NBOOLS - 1)
/* Enum declaration for ip2k hardware types. */
typedef enum cgen_hw_type {
HW_H_MEMORY, HW_H_SINT, HW_H_UINT, HW_H_ADDR
, HW_H_IADDR, HW_H_SPR, HW_H_REGISTERS, HW_H_STACK
, HW_H_PABITS, HW_H_ZBIT, HW_H_CBIT, HW_H_DCBIT
, HW_H_PC, HW_MAX
} CGEN_HW_TYPE;
#define MAX_HW ((int) HW_MAX)
/* Operand attribute indices. */
/* Enum declaration for cgen_operand attrs. */
typedef enum cgen_operand_attr {
CGEN_OPERAND_VIRTUAL, CGEN_OPERAND_PCREL_ADDR, CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_SIGN_OPT
, CGEN_OPERAND_SIGNED, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_RELAX, CGEN_OPERAND_SEM_ONLY
, CGEN_OPERAND_END_BOOLS, CGEN_OPERAND_START_NBOOLS = 31, CGEN_OPERAND_MACH, CGEN_OPERAND_END_NBOOLS
} CGEN_OPERAND_ATTR;
/* Number of non-boolean elements in cgen_operand_attr. */
#define CGEN_OPERAND_NBOOL_ATTRS (CGEN_OPERAND_END_NBOOLS - CGEN_OPERAND_START_NBOOLS - 1)
/* Enum declaration for ip2k operand types. */
typedef enum cgen_operand_type {
IP2K_OPERAND_PC, IP2K_OPERAND_ADDR16CJP, IP2K_OPERAND_FR, IP2K_OPERAND_LIT8
, IP2K_OPERAND_BITNO, IP2K_OPERAND_ADDR16P, IP2K_OPERAND_ADDR16H, IP2K_OPERAND_ADDR16L
, IP2K_OPERAND_RETI3, IP2K_OPERAND_PABITS, IP2K_OPERAND_ZBIT, IP2K_OPERAND_CBIT
, IP2K_OPERAND_DCBIT, IP2K_OPERAND_MAX
} CGEN_OPERAND_TYPE;
/* Number of operands types. */
#define MAX_OPERANDS 13
/* Maximum number of operands referenced by any insn. */
#define MAX_OPERAND_INSTANCES 8
/* Insn attribute indices. */
/* Enum declaration for cgen_insn attrs. */
typedef enum cgen_insn_attr {
CGEN_INSN_ALIAS, CGEN_INSN_VIRTUAL, CGEN_INSN_UNCOND_CTI, CGEN_INSN_COND_CTI
, CGEN_INSN_SKIP_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_RELAXABLE, CGEN_INSN_RELAX
, CGEN_INSN_NO_DIS, CGEN_INSN_PBB, CGEN_INSN_EXT_SKIP_INSN, CGEN_INSN_SKIPA
, CGEN_INSN_END_BOOLS, CGEN_INSN_START_NBOOLS = 31, CGEN_INSN_MACH, CGEN_INSN_END_NBOOLS
} CGEN_INSN_ATTR;
/* Number of non-boolean elements in cgen_insn_attr. */
#define CGEN_INSN_NBOOL_ATTRS (CGEN_INSN_END_NBOOLS - CGEN_INSN_START_NBOOLS - 1)
/* cgen.h uses things we just defined. */
#include "opcode/cgen.h"
/* Attributes. */
extern const CGEN_ATTR_TABLE ip2k_cgen_hardware_attr_table[];
extern const CGEN_ATTR_TABLE ip2k_cgen_ifield_attr_table[];
extern const CGEN_ATTR_TABLE ip2k_cgen_operand_attr_table[];
extern const CGEN_ATTR_TABLE ip2k_cgen_insn_attr_table[];
/* Hardware decls. */
#endif /* IP2K_CPU_H */

743
opcodes/ip2k-dis.c Normal file
View File

@ -0,0 +1,743 @@
/* Disassembler interface for targets using CGEN. -*- C -*-
CGEN: Cpu tools GENerator
THIS FILE IS MACHINE GENERATED WITH CGEN.
- the resultant file is machine generated, cgen-dis.in isn't
Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU Binutils and GDB, the GNU debugger.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
Keep that in mind. */
#include "sysdep.h"
#include <stdio.h>
#include "ansidecl.h"
#include "dis-asm.h"
#include "bfd.h"
#include "symcat.h"
#include "ip2k-desc.h"
#include "ip2k-opc.h"
#include "opintl.h"
/* Default text to print if an instruction isn't recognized. */
#define UNKNOWN_INSN_MSG _("*unknown*")
static void print_normal
PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned int, bfd_vma, int));
static void print_address
PARAMS ((CGEN_CPU_DESC, PTR, bfd_vma, unsigned int, bfd_vma, int));
static void print_keyword
PARAMS ((CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int));
static void print_insn_normal
PARAMS ((CGEN_CPU_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *,
bfd_vma, int));
static int print_insn
PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *, char *, unsigned));
static int default_print_insn
PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *));
static int read_insn
PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *, char *, int,
CGEN_EXTRACT_INFO *, unsigned long *));
/* -- disassembler routines inserted here */
/* -- dis.c */
static void
print_fr (cd, dis_info, value, attrs, pc, length)
CGEN_CPU_DESC cd;
PTR dis_info;
long value;
unsigned int attrs;
bfd_vma pc;
int length;
{
disassemble_info *info = (disassemble_info *) dis_info;
const CGEN_KEYWORD_ENTRY *ke;
extern CGEN_KEYWORD ip2k_cgen_opval_register_names;
long offsettest;
long offsetvalue;
if ( value == 0 ) /* This is (IP) */
{
(*info->fprintf_func) (info->stream, "%s", "(IP)");
return;
}
offsettest = value >> 7;
offsetvalue = value & 0x7F;
/* Check to see if first two bits are 10 -> (DP) */
if ( offsettest == 2 )
{
if ( offsetvalue == 0 )
(*info->fprintf_func) (info->stream, "%s","(DP)");
else
(*info->fprintf_func) (info->stream, "$%x%s",offsetvalue, "(DP)");
return;
}
/* Check to see if first two bits are 11 -> (SP) */
if ( offsettest == 3 )
{
if ( offsetvalue == 0 )
(*info->fprintf_func) (info->stream, "%s", "(SP)");
else
(*info->fprintf_func) (info->stream, "$%x%s", offsetvalue,"(SP)");
return;
}
/* Attempt to print as a register keyword. */
ke = cgen_keyword_lookup_value (& ip2k_cgen_opval_register_names, value);
if (ke != NULL)
{
(*info->fprintf_func) (info->stream, "%s", ke->name);
return;
}
/* Print as an address literal. */
(*info->fprintf_func) (info->stream, "$%02x", value);
}
static void
print_dollarhex (cd, dis_info, value, attrs, pc, length)
CGEN_CPU_DESC cd;
PTR dis_info;
long value;
unsigned int attrs;
bfd_vma pc;
int length;
{
disassemble_info *info = (disassemble_info *) dis_info;
(*info->fprintf_func) (info->stream, "$%x", value);
}
static void
print_dollarhex8 (cd, dis_info, value, attrs, pc, length)
CGEN_CPU_DESC cd;
PTR dis_info;
long value;
unsigned int attrs;
bfd_vma pc;
int length;
{
disassemble_info *info = (disassemble_info *) dis_info;
(*info->fprintf_func) (info->stream, "$%02x", value);
}
static void
print_dollarhex16 (cd, dis_info, value, attrs, pc, length)
CGEN_CPU_DESC cd;
PTR dis_info;
long value;
unsigned int attrs;
bfd_vma pc;
int length;
{
disassemble_info *info = (disassemble_info *) dis_info;
(*info->fprintf_func) (info->stream, "$%04x", value);
}
static void
print_dollarhex_addr16h (cd, dis_info, value, attrs, pc, length)
CGEN_CPU_DESC cd;
PTR dis_info;
long value;
unsigned int attrs;
bfd_vma pc;
int length;
{
disassemble_info *info = (disassemble_info *) dis_info;
/* This is a loadh instruction. Shift the value to the left */
/* by 8 bits so that disassembled code will reassemble properly. */
value = ((value << 8) & 0xFF00);
(*info->fprintf_func) (info->stream, "$%04x", value);
}
static void
print_dollarhex_addr16l (cd, dis_info, value, attrs, pc, length)
CGEN_CPU_DESC cd;
PTR dis_info;
long value;
unsigned int attrs;
bfd_vma pc;
int length;
{
disassemble_info *info = (disassemble_info *) dis_info;
(*info->fprintf_func) (info->stream, "$%04x", value);
}
static void
print_dollarhex_p (cd, dis_info, value, attrs, pc, length)
CGEN_CPU_DESC cd;
PTR dis_info;
long value;
unsigned int attrs;
bfd_vma pc;
int length;
{
disassemble_info *info = (disassemble_info *) dis_info;
value = ((value << 14) & 0x1C000);
;value = (value & 0x1FFFF);
(*info->fprintf_func) (info->stream, "$%05x", value);
}
static void
print_dollarhex_cj (cd, dis_info, value, attrs, pc, length)
CGEN_CPU_DESC cd;
PTR dis_info;
long value;
unsigned int attrs;
bfd_vma pc;
int length;
{
disassemble_info *info = (disassemble_info *) dis_info;
value = ((value << 1) & 0x1FFFF);
(*info->fprintf_func) (info->stream, "$%05x", value);
}
static void
print_decimal (cd, dis_info, value, attrs, pc, length)
CGEN_CPU_DESC cd;
PTR dis_info;
long value;
unsigned int attrs;
bfd_vma pc;
int length;
{
disassemble_info *info = (disassemble_info *) dis_info;
(*info->fprintf_func) (info->stream, "%d", value);
}
/* -- */
void ip2k_cgen_print_operand
PARAMS ((CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *,
void const *, bfd_vma, int));
/* Main entry point for printing operands.
XINFO is a `void *' and not a `disassemble_info *' to not put a requirement
of dis-asm.h on cgen.h.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `print_insn_normal', but keeping it
separate makes clear the interface between `print_insn_normal' and each of
the handlers. */
void
ip2k_cgen_print_operand (cd, opindex, xinfo, fields, attrs, pc, length)
CGEN_CPU_DESC cd;
int opindex;
PTR xinfo;
CGEN_FIELDS *fields;
void const *attrs ATTRIBUTE_UNUSED;
bfd_vma pc;
int length;
{
disassemble_info *info = (disassemble_info *) xinfo;
switch (opindex)
{
case IP2K_OPERAND_ADDR16CJP :
print_dollarhex_cj (cd, info, fields->f_addr16cjp, 0|(1<<CGEN_OPERAND_ABS_ADDR), pc, length);
break;
case IP2K_OPERAND_ADDR16H :
print_dollarhex_addr16h (cd, info, fields->f_imm8, 0, pc, length);
break;
case IP2K_OPERAND_ADDR16L :
print_dollarhex_addr16l (cd, info, fields->f_imm8, 0, pc, length);
break;
case IP2K_OPERAND_ADDR16P :
print_dollarhex_p (cd, info, fields->f_page3, 0, pc, length);
break;
case IP2K_OPERAND_BITNO :
print_decimal (cd, info, fields->f_bitno, 0, pc, length);
break;
case IP2K_OPERAND_CBIT :
print_normal (cd, info, 0, 0, pc, length);
break;
case IP2K_OPERAND_DCBIT :
print_normal (cd, info, 0, 0, pc, length);
break;
case IP2K_OPERAND_FR :
print_fr (cd, info, fields->f_reg, 0|(1<<CGEN_OPERAND_ABS_ADDR), pc, length);
break;
case IP2K_OPERAND_LIT8 :
print_dollarhex8 (cd, info, fields->f_imm8, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
break;
case IP2K_OPERAND_PABITS :
print_normal (cd, info, 0, 0, pc, length);
break;
case IP2K_OPERAND_RETI3 :
print_dollarhex (cd, info, fields->f_reti3, 0, pc, length);
break;
case IP2K_OPERAND_ZBIT :
print_normal (cd, info, 0, 0, pc, length);
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
opindex);
abort ();
}
}
cgen_print_fn * const ip2k_cgen_print_handlers[] =
{
print_insn_normal,
};
void
ip2k_cgen_init_dis (cd)
CGEN_CPU_DESC cd;
{
ip2k_cgen_init_opcode_table (cd);
ip2k_cgen_init_ibld_table (cd);
cd->print_handlers = & ip2k_cgen_print_handlers[0];
cd->print_operand = ip2k_cgen_print_operand;
}
/* Default print handler. */
static void
print_normal (cd, dis_info, value, attrs, pc, length)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
PTR dis_info;
long value;
unsigned int attrs;
bfd_vma pc ATTRIBUTE_UNUSED;
int length ATTRIBUTE_UNUSED;
{
disassemble_info *info = (disassemble_info *) dis_info;
#ifdef CGEN_PRINT_NORMAL
CGEN_PRINT_NORMAL (cd, info, value, attrs, pc, length);
#endif
/* Print the operand as directed by the attributes. */
if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
; /* nothing to do */
else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
(*info->fprintf_func) (info->stream, "%ld", value);
else
(*info->fprintf_func) (info->stream, "0x%lx", value);
}
/* Default address handler. */
static void
print_address (cd, dis_info, value, attrs, pc, length)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
PTR dis_info;
bfd_vma value;
unsigned int attrs;
bfd_vma pc ATTRIBUTE_UNUSED;
int length ATTRIBUTE_UNUSED;
{
disassemble_info *info = (disassemble_info *) dis_info;
#ifdef CGEN_PRINT_ADDRESS
CGEN_PRINT_ADDRESS (cd, info, value, attrs, pc, length);
#endif
/* Print the operand as directed by the attributes. */
if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
; /* nothing to do */
else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
(*info->print_address_func) (value, info);
else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
(*info->print_address_func) (value, info);
else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
(*info->fprintf_func) (info->stream, "%ld", (long) value);
else
(*info->fprintf_func) (info->stream, "0x%lx", (long) value);
}
/* Keyword print handler. */
static void
print_keyword (cd, dis_info, keyword_table, value, attrs)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
PTR dis_info;
CGEN_KEYWORD *keyword_table;
long value;
unsigned int attrs ATTRIBUTE_UNUSED;
{
disassemble_info *info = (disassemble_info *) dis_info;
const CGEN_KEYWORD_ENTRY *ke;
ke = cgen_keyword_lookup_value (keyword_table, value);
if (ke != NULL)
(*info->fprintf_func) (info->stream, "%s", ke->name);
else
(*info->fprintf_func) (info->stream, "???");
}
/* Default insn printer.
DIS_INFO is defined as `PTR' so the disassembler needn't know anything
about disassemble_info. */
static void
print_insn_normal (cd, dis_info, insn, fields, pc, length)
CGEN_CPU_DESC cd;
PTR dis_info;
const CGEN_INSN *insn;
CGEN_FIELDS *fields;
bfd_vma pc;
int length;
{
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
disassemble_info *info = (disassemble_info *) dis_info;
const CGEN_SYNTAX_CHAR_TYPE *syn;
CGEN_INIT_PRINT (cd);
for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
{
if (CGEN_SYNTAX_MNEMONIC_P (*syn))
{
(*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
continue;
}
if (CGEN_SYNTAX_CHAR_P (*syn))
{
(*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
continue;
}
/* We have an operand. */
ip2k_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
fields, CGEN_INSN_ATTRS (insn), pc, length);
}
}
/* Subroutine of print_insn. Reads an insn into the given buffers and updates
the extract info.
Returns 0 if all is well, non-zero otherwise. */
static int
read_insn (cd, pc, info, buf, buflen, ex_info, insn_value)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
bfd_vma pc;
disassemble_info *info;
char *buf;
int buflen;
CGEN_EXTRACT_INFO *ex_info;
unsigned long *insn_value;
{
int status = (*info->read_memory_func) (pc, buf, buflen, info);
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return -1;
}
ex_info->dis_info = info;
ex_info->valid = (1 << buflen) - 1;
ex_info->insn_bytes = buf;
*insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
return 0;
}
/* Utility to print an insn.
BUF is the base part of the insn, target byte order, BUFLEN bytes long.
The result is the size of the insn in bytes or zero for an unknown insn
or -1 if an error occurs fetching data (memory_error_func will have
been called). */
static int
print_insn (cd, pc, info, buf, buflen)
CGEN_CPU_DESC cd;
bfd_vma pc;
disassemble_info *info;
char *buf;
unsigned int buflen;
{
CGEN_INSN_INT insn_value;
const CGEN_INSN_LIST *insn_list;
CGEN_EXTRACT_INFO ex_info;
int basesize;
/* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
basesize = cd->base_insn_bitsize < buflen * 8 ?
cd->base_insn_bitsize : buflen * 8;
insn_value = cgen_get_insn_value (cd, buf, basesize);
/* Fill in ex_info fields like read_insn would. Don't actually call
read_insn, since the incoming buffer is already read (and possibly
modified a la m32r). */
ex_info.valid = (1 << buflen) - 1;
ex_info.dis_info = info;
ex_info.insn_bytes = buf;
/* The instructions are stored in hash lists.
Pick the first one and keep trying until we find the right one. */
insn_list = CGEN_DIS_LOOKUP_INSN (cd, buf, insn_value);
while (insn_list != NULL)
{
const CGEN_INSN *insn = insn_list->insn;
CGEN_FIELDS fields;
int length;
unsigned long insn_value_cropped;
#ifdef CGEN_VALIDATE_INSN_SUPPORTED
/* Not needed as insn shouldn't be in hash lists if not supported. */
/* Supported by this cpu? */
if (! ip2k_cgen_insn_supported (cd, insn))
{
insn_list = CGEN_DIS_NEXT_INSN (insn_list);
continue;
}
#endif
/* Basic bit mask must be correct. */
/* ??? May wish to allow target to defer this check until the extract
handler. */
/* Base size may exceed this instruction's size. Extract the
relevant part from the buffer. */
if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
(unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
info->endian == BFD_ENDIAN_BIG);
else
insn_value_cropped = insn_value;
if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
== CGEN_INSN_BASE_VALUE (insn))
{
/* Printing is handled in two passes. The first pass parses the
machine insn and extracts the fields. The second pass prints
them. */
/* Make sure the entire insn is loaded into insn_value, if it
can fit. */
if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) &&
(unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
{
unsigned long full_insn_value;
int rc = read_insn (cd, pc, info, buf,
CGEN_INSN_BITSIZE (insn) / 8,
& ex_info, & full_insn_value);
if (rc != 0)
return rc;
length = CGEN_EXTRACT_FN (cd, insn)
(cd, insn, &ex_info, full_insn_value, &fields, pc);
}
else
length = CGEN_EXTRACT_FN (cd, insn)
(cd, insn, &ex_info, insn_value_cropped, &fields, pc);
/* length < 0 -> error */
if (length < 0)
return length;
if (length > 0)
{
CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
/* length is in bits, result is in bytes */
return length / 8;
}
}
insn_list = CGEN_DIS_NEXT_INSN (insn_list);
}
return 0;
}
/* Default value for CGEN_PRINT_INSN.
The result is the size of the insn in bytes or zero for an unknown insn
or -1 if an error occured fetching bytes. */
#ifndef CGEN_PRINT_INSN
#define CGEN_PRINT_INSN default_print_insn
#endif
static int
default_print_insn (cd, pc, info)
CGEN_CPU_DESC cd;
bfd_vma pc;
disassemble_info *info;
{
char buf[CGEN_MAX_INSN_SIZE];
int buflen;
int status;
/* Attempt to read the base part of the insn. */
buflen = cd->base_insn_bitsize / 8;
status = (*info->read_memory_func) (pc, buf, buflen, info);
/* Try again with the minimum part, if min < base. */
if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
{
buflen = cd->min_insn_bitsize / 8;
status = (*info->read_memory_func) (pc, buf, buflen, info);
}
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return -1;
}
return print_insn (cd, pc, info, buf, buflen);
}
/* Main entry point.
Print one instruction from PC on INFO->STREAM.
Return the size of the instruction (in bytes). */
typedef struct cpu_desc_list {
struct cpu_desc_list *next;
int isa;
int mach;
int endian;
CGEN_CPU_DESC cd;
} cpu_desc_list;
int
print_insn_ip2k (pc, info)
bfd_vma pc;
disassemble_info *info;
{
static cpu_desc_list *cd_list = 0;
cpu_desc_list *cl = 0;
static CGEN_CPU_DESC cd = 0;
static int prev_isa;
static int prev_mach;
static int prev_endian;
int length;
int isa,mach;
int endian = (info->endian == BFD_ENDIAN_BIG
? CGEN_ENDIAN_BIG
: CGEN_ENDIAN_LITTLE);
enum bfd_architecture arch;
/* ??? gdb will set mach but leave the architecture as "unknown" */
#ifndef CGEN_BFD_ARCH
#define CGEN_BFD_ARCH bfd_arch_ip2k
#endif
arch = info->arch;
if (arch == bfd_arch_unknown)
arch = CGEN_BFD_ARCH;
/* There's no standard way to compute the machine or isa number
so we leave it to the target. */
#ifdef CGEN_COMPUTE_MACH
mach = CGEN_COMPUTE_MACH (info);
#else
mach = info->mach;
#endif
#ifdef CGEN_COMPUTE_ISA
isa = CGEN_COMPUTE_ISA (info);
#else
isa = info->insn_sets;
#endif
/* If we've switched cpu's, try to find a handle we've used before */
if (cd
&& (isa != prev_isa
|| mach != prev_mach
|| endian != prev_endian))
{
cd = 0;
for (cl = cd_list; cl; cl = cl->next)
{
if (cl->isa == isa &&
cl->mach == mach &&
cl->endian == endian)
{
cd = cl->cd;
break;
}
}
}
/* If we haven't initialized yet, initialize the opcode table. */
if (! cd)
{
const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
const char *mach_name;
if (!arch_type)
abort ();
mach_name = arch_type->printable_name;
prev_isa = isa;
prev_mach = mach;
prev_endian = endian;
cd = ip2k_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
CGEN_CPU_OPEN_BFDMACH, mach_name,
CGEN_CPU_OPEN_ENDIAN, prev_endian,
CGEN_CPU_OPEN_END);
if (!cd)
abort ();
/* save this away for future reference */
cl = xmalloc (sizeof (struct cpu_desc_list));
cl->cd = cd;
cl->isa = isa;
cl->mach = mach;
cl->endian = endian;
cl->next = cd_list;
cd_list = cl;
ip2k_cgen_init_dis (cd);
}
/* We try to have as much common code as possible.
But at this point some targets need to take over. */
/* ??? Some targets may need a hook elsewhere. Try to avoid this,
but if not possible try to move this hook elsewhere rather than
have two hooks. */
length = CGEN_PRINT_INSN (cd, pc, info);
if (length > 0)
return length;
if (length < 0)
return -1;
(*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
return cd->default_insn_bitsize / 8;
}

952
opcodes/ip2k-ibld.c Normal file
View File

@ -0,0 +1,952 @@
/* Instruction building/extraction support for ip2k. -*- C -*-
THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
- the resultant file is machine generated, cgen-ibld.in isn't
Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU Binutils and GDB, the GNU debugger.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
Keep that in mind. */
#include "sysdep.h"
#include <stdio.h>
#include "ansidecl.h"
#include "dis-asm.h"
#include "bfd.h"
#include "symcat.h"
#include "ip2k-desc.h"
#include "ip2k-opc.h"
#include "opintl.h"
#include "safe-ctype.h"
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#undef max
#define max(a,b) ((a) > (b) ? (a) : (b))
/* Used by the ifield rtx function. */
#define FLD(f) (fields->f)
static const char * insert_normal
PARAMS ((CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR));
static const char * insert_insn_normal
PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *,
CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
static int extract_normal
PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
unsigned int, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, bfd_vma, long *));
static int extract_insn_normal
PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
#if CGEN_INT_INSN_P
static void put_insn_int_value
PARAMS ((CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT));
#endif
#if ! CGEN_INT_INSN_P
static CGEN_INLINE void insert_1
PARAMS ((CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *));
static CGEN_INLINE int fill_cache
PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma));
static CGEN_INLINE long extract_1
PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int,
unsigned char *, bfd_vma));
#endif
/* Operand insertion. */
#if ! CGEN_INT_INSN_P
/* Subroutine of insert_normal. */
static CGEN_INLINE void
insert_1 (cd, value, start, length, word_length, bufp)
CGEN_CPU_DESC cd;
unsigned long value;
int start,length,word_length;
unsigned char *bufp;
{
unsigned long x,mask;
int shift;
x = cgen_get_insn_value (cd, bufp, word_length);
/* Written this way to avoid undefined behaviour. */
mask = (((1L << (length - 1)) - 1) << 1) | 1;
if (CGEN_INSN_LSB0_P)
shift = (start + 1) - length;
else
shift = (word_length - (start + length));
x = (x & ~(mask << shift)) | ((value & mask) << shift);
cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
}
#endif /* ! CGEN_INT_INSN_P */
/* Default insertion routine.
ATTRS is a mask of the boolean attributes.
WORD_OFFSET is the offset in bits from the start of the insn of the value.
WORD_LENGTH is the length of the word in bits in which the value resides.
START is the starting bit number in the word, architecture origin.
LENGTH is the length of VALUE in bits.
TOTAL_LENGTH is the total length of the insn in bits.
The result is an error message or NULL if success. */
/* ??? This duplicates functionality with bfd's howto table and
bfd_install_relocation. */
/* ??? This doesn't handle bfd_vma's. Create another function when
necessary. */
static const char *
insert_normal (cd, value, attrs, word_offset, start, length, word_length,
total_length, buffer)
CGEN_CPU_DESC cd;
long value;
unsigned int attrs;
unsigned int word_offset, start, length, word_length, total_length;
CGEN_INSN_BYTES_PTR buffer;
{
static char errbuf[100];
/* Written this way to avoid undefined behaviour. */
unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
/* If LENGTH is zero, this operand doesn't contribute to the value. */
if (length == 0)
return NULL;
#if 0
if (CGEN_INT_INSN_P
&& word_offset != 0)
abort ();
#endif
if (word_length > 32)
abort ();
/* For architectures with insns smaller than the base-insn-bitsize,
word_length may be too big. */
if (cd->min_insn_bitsize < cd->base_insn_bitsize)
{
if (word_offset == 0
&& word_length > total_length)
word_length = total_length;
}
/* Ensure VALUE will fit. */
if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
{
long minval = - (1L << (length - 1));
unsigned long maxval = mask;
if ((value > 0 && (unsigned long) value > maxval)
|| value < minval)
{
/* xgettext:c-format */
sprintf (errbuf,
_("operand out of range (%ld not between %ld and %lu)"),
value, minval, maxval);
return errbuf;
}
}
else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
{
unsigned long maxval = mask;
if ((unsigned long) value > maxval)
{
/* xgettext:c-format */
sprintf (errbuf,
_("operand out of range (%lu not between 0 and %lu)"),
value, maxval);
return errbuf;
}
}
else
{
if (! cgen_signed_overflow_ok_p (cd))
{
long minval = - (1L << (length - 1));
long maxval = (1L << (length - 1)) - 1;
if (value < minval || value > maxval)
{
sprintf
/* xgettext:c-format */
(errbuf, _("operand out of range (%ld not between %ld and %ld)"),
value, minval, maxval);
return errbuf;
}
}
}
#if CGEN_INT_INSN_P
{
int shift;
if (CGEN_INSN_LSB0_P)
shift = (word_offset + start + 1) - length;
else
shift = total_length - (word_offset + start + length);
*buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
}
#else /* ! CGEN_INT_INSN_P */
{
unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
insert_1 (cd, value, start, length, word_length, bufp);
}
#endif /* ! CGEN_INT_INSN_P */
return NULL;
}
/* Default insn builder (insert handler).
The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
recorded in host byte order, otherwise BUFFER is an array of bytes
and the value is recorded in target byte order).
The result is an error message or NULL if success. */
static const char *
insert_insn_normal (cd, insn, fields, buffer, pc)
CGEN_CPU_DESC cd;
const CGEN_INSN * insn;
CGEN_FIELDS * fields;
CGEN_INSN_BYTES_PTR buffer;
bfd_vma pc;
{
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
unsigned long value;
const CGEN_SYNTAX_CHAR_TYPE * syn;
CGEN_INIT_INSERT (cd);
value = CGEN_INSN_BASE_VALUE (insn);
/* If we're recording insns as numbers (rather than a string of bytes),
target byte order handling is deferred until later. */
#if CGEN_INT_INSN_P
put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
CGEN_FIELDS_BITSIZE (fields), value);
#else
cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
(unsigned) CGEN_FIELDS_BITSIZE (fields)),
value);
#endif /* ! CGEN_INT_INSN_P */
/* ??? It would be better to scan the format's fields.
Still need to be able to insert a value based on the operand though;
e.g. storing a branch displacement that got resolved later.
Needs more thought first. */
for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
{
const char *errmsg;
if (CGEN_SYNTAX_CHAR_P (* syn))
continue;
errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
fields, buffer, pc);
if (errmsg)
return errmsg;
}
return NULL;
}
#if CGEN_INT_INSN_P
/* Cover function to store an insn value into an integral insn. Must go here
because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
static void
put_insn_int_value (cd, buf, length, insn_length, value)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
CGEN_INSN_BYTES_PTR buf;
int length;
int insn_length;
CGEN_INSN_INT value;
{
/* For architectures with insns smaller than the base-insn-bitsize,
length may be too big. */
if (length > insn_length)
*buf = value;
else
{
int shift = insn_length - length;
/* Written this way to avoid undefined behaviour. */
CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
*buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
}
}
#endif
/* Operand extraction. */
#if ! CGEN_INT_INSN_P
/* Subroutine of extract_normal.
Ensure sufficient bytes are cached in EX_INFO.
OFFSET is the offset in bytes from the start of the insn of the value.
BYTES is the length of the needed value.
Returns 1 for success, 0 for failure. */
static CGEN_INLINE int
fill_cache (cd, ex_info, offset, bytes, pc)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
CGEN_EXTRACT_INFO *ex_info;
int offset, bytes;
bfd_vma pc;
{
/* It's doubtful that the middle part has already been fetched so
we don't optimize that case. kiss. */
unsigned int mask;
disassemble_info *info = (disassemble_info *) ex_info->dis_info;
/* First do a quick check. */
mask = (1 << bytes) - 1;
if (((ex_info->valid >> offset) & mask) == mask)
return 1;
/* Search for the first byte we need to read. */
for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
if (! (mask & ex_info->valid))
break;
if (bytes)
{
int status;
pc += offset;
status = (*info->read_memory_func)
(pc, ex_info->insn_bytes + offset, bytes, info);
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return 0;
}
ex_info->valid |= ((1 << bytes) - 1) << offset;
}
return 1;
}
/* Subroutine of extract_normal. */
static CGEN_INLINE long
extract_1 (cd, ex_info, start, length, word_length, bufp, pc)
CGEN_CPU_DESC cd;
CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED;
int start,length,word_length;
unsigned char *bufp;
bfd_vma pc ATTRIBUTE_UNUSED;
{
unsigned long x;
int shift;
#if 0
int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
#endif
x = cgen_get_insn_value (cd, bufp, word_length);
if (CGEN_INSN_LSB0_P)
shift = (start + 1) - length;
else
shift = (word_length - (start + length));
return x >> shift;
}
#endif /* ! CGEN_INT_INSN_P */
/* Default extraction routine.
INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
or sometimes less for cases like the m32r where the base insn size is 32
but some insns are 16 bits.
ATTRS is a mask of the boolean attributes. We only need `SIGNED',
but for generality we take a bitmask of all of them.
WORD_OFFSET is the offset in bits from the start of the insn of the value.
WORD_LENGTH is the length of the word in bits in which the value resides.
START is the starting bit number in the word, architecture origin.
LENGTH is the length of VALUE in bits.
TOTAL_LENGTH is the total length of the insn in bits.
Returns 1 for success, 0 for failure. */
/* ??? The return code isn't properly used. wip. */
/* ??? This doesn't handle bfd_vma's. Create another function when
necessary. */
static int
extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
word_length, total_length, pc, valuep)
CGEN_CPU_DESC cd;
#if ! CGEN_INT_INSN_P
CGEN_EXTRACT_INFO *ex_info;
#else
CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED;
#endif
CGEN_INSN_INT insn_value;
unsigned int attrs;
unsigned int word_offset, start, length, word_length, total_length;
#if ! CGEN_INT_INSN_P
bfd_vma pc;
#else
bfd_vma pc ATTRIBUTE_UNUSED;
#endif
long *valuep;
{
long value, mask;
/* If LENGTH is zero, this operand doesn't contribute to the value
so give it a standard value of zero. */
if (length == 0)
{
*valuep = 0;
return 1;
}
#if 0
if (CGEN_INT_INSN_P
&& word_offset != 0)
abort ();
#endif
if (word_length > 32)
abort ();
/* For architectures with insns smaller than the insn-base-bitsize,
word_length may be too big. */
if (cd->min_insn_bitsize < cd->base_insn_bitsize)
{
if (word_offset == 0
&& word_length > total_length)
word_length = total_length;
}
/* Does the value reside in INSN_VALUE, and at the right alignment? */
if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
{
if (CGEN_INSN_LSB0_P)
value = insn_value >> ((word_offset + start + 1) - length);
else
value = insn_value >> (total_length - ( word_offset + start + length));
}
#if ! CGEN_INT_INSN_P
else
{
unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
if (word_length > 32)
abort ();
if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
return 0;
value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
}
#endif /* ! CGEN_INT_INSN_P */
/* Written this way to avoid undefined behaviour. */
mask = (((1L << (length - 1)) - 1) << 1) | 1;
value &= mask;
/* sign extend? */
if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
&& (value & (1L << (length - 1))))
value |= ~mask;
*valuep = value;
return 1;
}
/* Default insn extractor.
INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
The extracted fields are stored in FIELDS.
EX_INFO is used to handle reading variable length insns.
Return the length of the insn in bits, or 0 if no match,
or -1 if an error occurs fetching data (memory_error_func will have
been called). */
static int
extract_insn_normal (cd, insn, ex_info, insn_value, fields, pc)
CGEN_CPU_DESC cd;
const CGEN_INSN *insn;
CGEN_EXTRACT_INFO *ex_info;
CGEN_INSN_INT insn_value;
CGEN_FIELDS *fields;
bfd_vma pc;
{
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
const CGEN_SYNTAX_CHAR_TYPE *syn;
CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
CGEN_INIT_EXTRACT (cd);
for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
{
int length;
if (CGEN_SYNTAX_CHAR_P (*syn))
continue;
length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
ex_info, insn_value, fields, pc);
if (length <= 0)
return length;
}
/* We recognized and successfully extracted this insn. */
return CGEN_INSN_BITSIZE (insn);
}
/* machine generated code added here */
const char * ip2k_cgen_insert_operand
PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
/* 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 *
ip2k_cgen_insert_operand (cd, opindex, fields, buffer, pc)
CGEN_CPU_DESC cd;
int opindex;
CGEN_FIELDS * fields;
CGEN_INSN_BYTES_PTR buffer;
bfd_vma pc ATTRIBUTE_UNUSED;
{
const char * errmsg = NULL;
unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
switch (opindex)
{
case IP2K_OPERAND_ADDR16CJP :
errmsg = insert_normal (cd, fields->f_addr16cjp, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 12, 13, 16, total_length, buffer);
break;
case IP2K_OPERAND_ADDR16H :
errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 7, 8, 16, total_length, buffer);
break;
case IP2K_OPERAND_ADDR16L :
errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 7, 8, 16, total_length, buffer);
break;
case IP2K_OPERAND_ADDR16P :
errmsg = insert_normal (cd, fields->f_page3, 0, 0, 2, 3, 16, total_length, buffer);
break;
case IP2K_OPERAND_BITNO :
errmsg = insert_normal (cd, fields->f_bitno, 0, 0, 11, 3, 16, total_length, buffer);
break;
case IP2K_OPERAND_CBIT :
break;
case IP2K_OPERAND_DCBIT :
break;
case IP2K_OPERAND_FR :
errmsg = insert_normal (cd, fields->f_reg, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 9, 16, total_length, buffer);
break;
case IP2K_OPERAND_LIT8 :
errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 7, 8, 16, total_length, buffer);
break;
case IP2K_OPERAND_PABITS :
break;
case IP2K_OPERAND_RETI3 :
errmsg = insert_normal (cd, fields->f_reti3, 0, 0, 2, 3, 16, total_length, buffer);
break;
case IP2K_OPERAND_ZBIT :
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
opindex);
abort ();
}
return errmsg;
}
int ip2k_cgen_extract_operand
PARAMS ((CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
CGEN_FIELDS *, bfd_vma));
/* Main entry point for operand extraction.
The result is <= 0 for error, >0 for success.
??? Actual values aren't well defined right now.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `print_insn_normal', but keeping it
separate makes clear the interface between `print_insn_normal' and each of
the handlers. */
int
ip2k_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
CGEN_CPU_DESC cd;
int opindex;
CGEN_EXTRACT_INFO *ex_info;
CGEN_INSN_INT insn_value;
CGEN_FIELDS * fields;
bfd_vma pc;
{
/* Assume success (for those operands that are nops). */
int length = 1;
unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
switch (opindex)
{
case IP2K_OPERAND_ADDR16CJP :
length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 12, 13, 16, total_length, pc, & fields->f_addr16cjp);
break;
case IP2K_OPERAND_ADDR16H :
length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 8, 16, total_length, pc, & fields->f_imm8);
break;
case IP2K_OPERAND_ADDR16L :
length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 8, 16, total_length, pc, & fields->f_imm8);
break;
case IP2K_OPERAND_ADDR16P :
length = extract_normal (cd, ex_info, insn_value, 0, 0, 2, 3, 16, total_length, pc, & fields->f_page3);
break;
case IP2K_OPERAND_BITNO :
length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 3, 16, total_length, pc, & fields->f_bitno);
break;
case IP2K_OPERAND_CBIT :
break;
case IP2K_OPERAND_DCBIT :
break;
case IP2K_OPERAND_FR :
length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 9, 16, total_length, pc, & fields->f_reg);
break;
case IP2K_OPERAND_LIT8 :
length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 8, 16, total_length, pc, & fields->f_imm8);
break;
case IP2K_OPERAND_PABITS :
break;
case IP2K_OPERAND_RETI3 :
length = extract_normal (cd, ex_info, insn_value, 0, 0, 2, 3, 16, total_length, pc, & fields->f_reti3);
break;
case IP2K_OPERAND_ZBIT :
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
opindex);
abort ();
}
return length;
}
cgen_insert_fn * const ip2k_cgen_insert_handlers[] =
{
insert_insn_normal,
};
cgen_extract_fn * const ip2k_cgen_extract_handlers[] =
{
extract_insn_normal,
};
int ip2k_cgen_get_int_operand
PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *));
bfd_vma ip2k_cgen_get_vma_operand
PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *));
/* 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
ip2k_cgen_get_int_operand (cd, opindex, fields)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
int opindex;
const CGEN_FIELDS * fields;
{
int value;
switch (opindex)
{
case IP2K_OPERAND_ADDR16CJP :
value = fields->f_addr16cjp;
break;
case IP2K_OPERAND_ADDR16H :
value = fields->f_imm8;
break;
case IP2K_OPERAND_ADDR16L :
value = fields->f_imm8;
break;
case IP2K_OPERAND_ADDR16P :
value = fields->f_page3;
break;
case IP2K_OPERAND_BITNO :
value = fields->f_bitno;
break;
case IP2K_OPERAND_CBIT :
value = 0;
break;
case IP2K_OPERAND_DCBIT :
value = 0;
break;
case IP2K_OPERAND_FR :
value = fields->f_reg;
break;
case IP2K_OPERAND_LIT8 :
value = fields->f_imm8;
break;
case IP2K_OPERAND_PABITS :
value = 0;
break;
case IP2K_OPERAND_RETI3 :
value = fields->f_reti3;
break;
case IP2K_OPERAND_ZBIT :
value = 0;
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
opindex);
abort ();
}
return value;
}
bfd_vma
ip2k_cgen_get_vma_operand (cd, opindex, fields)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
int opindex;
const CGEN_FIELDS * fields;
{
bfd_vma value;
switch (opindex)
{
case IP2K_OPERAND_ADDR16CJP :
value = fields->f_addr16cjp;
break;
case IP2K_OPERAND_ADDR16H :
value = fields->f_imm8;
break;
case IP2K_OPERAND_ADDR16L :
value = fields->f_imm8;
break;
case IP2K_OPERAND_ADDR16P :
value = fields->f_page3;
break;
case IP2K_OPERAND_BITNO :
value = fields->f_bitno;
break;
case IP2K_OPERAND_CBIT :
value = 0;
break;
case IP2K_OPERAND_DCBIT :
value = 0;
break;
case IP2K_OPERAND_FR :
value = fields->f_reg;
break;
case IP2K_OPERAND_LIT8 :
value = fields->f_imm8;
break;
case IP2K_OPERAND_PABITS :
value = 0;
break;
case IP2K_OPERAND_RETI3 :
value = fields->f_reti3;
break;
case IP2K_OPERAND_ZBIT :
value = 0;
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
opindex);
abort ();
}
return value;
}
void ip2k_cgen_set_int_operand
PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, int));
void ip2k_cgen_set_vma_operand
PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma));
/* 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
ip2k_cgen_set_int_operand (cd, opindex, fields, value)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
int opindex;
CGEN_FIELDS * fields;
int value;
{
switch (opindex)
{
case IP2K_OPERAND_ADDR16CJP :
fields->f_addr16cjp = value;
break;
case IP2K_OPERAND_ADDR16H :
fields->f_imm8 = value;
break;
case IP2K_OPERAND_ADDR16L :
fields->f_imm8 = value;
break;
case IP2K_OPERAND_ADDR16P :
fields->f_page3 = value;
break;
case IP2K_OPERAND_BITNO :
fields->f_bitno = value;
break;
case IP2K_OPERAND_CBIT :
break;
case IP2K_OPERAND_DCBIT :
break;
case IP2K_OPERAND_FR :
fields->f_reg = value;
break;
case IP2K_OPERAND_LIT8 :
fields->f_imm8 = value;
break;
case IP2K_OPERAND_PABITS :
break;
case IP2K_OPERAND_RETI3 :
fields->f_reti3 = value;
break;
case IP2K_OPERAND_ZBIT :
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
opindex);
abort ();
}
}
void
ip2k_cgen_set_vma_operand (cd, opindex, fields, value)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
int opindex;
CGEN_FIELDS * fields;
bfd_vma value;
{
switch (opindex)
{
case IP2K_OPERAND_ADDR16CJP :
fields->f_addr16cjp = value;
break;
case IP2K_OPERAND_ADDR16H :
fields->f_imm8 = value;
break;
case IP2K_OPERAND_ADDR16L :
fields->f_imm8 = value;
break;
case IP2K_OPERAND_ADDR16P :
fields->f_page3 = value;
break;
case IP2K_OPERAND_BITNO :
fields->f_bitno = value;
break;
case IP2K_OPERAND_CBIT :
break;
case IP2K_OPERAND_DCBIT :
break;
case IP2K_OPERAND_FR :
fields->f_reg = value;
break;
case IP2K_OPERAND_LIT8 :
fields->f_imm8 = value;
break;
case IP2K_OPERAND_PABITS :
break;
case IP2K_OPERAND_RETI3 :
fields->f_reti3 = value;
break;
case IP2K_OPERAND_ZBIT :
break;
default :
/* xgettext:c-format */
fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
opindex);
abort ();
}
}
/* Function to call before using the instruction builder tables. */
void
ip2k_cgen_init_ibld_table (cd)
CGEN_CPU_DESC cd;
{
cd->insert_handlers = & ip2k_cgen_insert_handlers[0];
cd->extract_handlers = & ip2k_cgen_extract_handlers[0];
cd->insert_operand = ip2k_cgen_insert_operand;
cd->extract_operand = ip2k_cgen_extract_operand;
cd->get_int_operand = ip2k_cgen_get_int_operand;
cd->set_int_operand = ip2k_cgen_set_int_operand;
cd->get_vma_operand = ip2k_cgen_get_vma_operand;
cd->set_vma_operand = ip2k_cgen_set_vma_operand;
}

914
opcodes/ip2k-opc.c Normal file
View File

@ -0,0 +1,914 @@
/* Instruction opcode table for ip2k.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sysdep.h"
#include "ansidecl.h"
#include "bfd.h"
#include "symcat.h"
#include "ip2k-desc.h"
#include "ip2k-opc.h"
#include "libiberty.h"
/* -- opc.c */
/* A better hash function for instruction mnemonics. */
unsigned int
ip2k_asm_hash (insn)
const char* insn;
{
unsigned int hash;
const char* m = insn;
for (hash = 0; *m && !isspace(*m); m++)
hash = (hash * 23) ^ (0x1F & tolower(*m));
/* printf ("%s %d\n", insn, (hash % CGEN_ASM_HASH_SIZE)); */
return hash % CGEN_ASM_HASH_SIZE;
}
/* -- asm.c */
/* The hash functions are recorded here to help keep assembler code out of
the disassembler and vice versa. */
static int asm_hash_insn_p PARAMS ((const CGEN_INSN *));
static unsigned int asm_hash_insn PARAMS ((const char *));
static int dis_hash_insn_p PARAMS ((const CGEN_INSN *));
static unsigned int dis_hash_insn PARAMS ((const char *, CGEN_INSN_INT));
/* Instruction formats. */
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define F(f) & ip2k_cgen_ifld_table[IP2K_##f]
#else
#define F(f) & ip2k_cgen_ifld_table[IP2K_/**/f]
#endif
static const CGEN_IFMT ifmt_empty = {
0, 0, 0x0, { { 0 } }
};
static const CGEN_IFMT ifmt_jmp = {
16, 16, 0xe000, { { F (F_OP3) }, { F (F_ADDR16CJP) }, { 0 } }
};
static const CGEN_IFMT ifmt_sb = {
16, 16, 0xf000, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
};
static const CGEN_IFMT ifmt_xorw_l = {
16, 16, 0xff00, { { F (F_OP4) }, { F (F_OP4MID) }, { F (F_IMM8) }, { 0 } }
};
static const CGEN_IFMT ifmt_loadl_a = {
16, 16, 0xff00, { { F (F_OP4) }, { F (F_OP4MID) }, { F (F_IMM8) }, { 0 } }
};
static const CGEN_IFMT ifmt_loadh_a = {
16, 16, 0xff00, { { F (F_OP4) }, { F (F_OP4MID) }, { F (F_IMM8) }, { 0 } }
};
static const CGEN_IFMT ifmt_addcfr_w = {
16, 16, 0xfe00, { { F (F_OP6) }, { F (F_DIR) }, { F (F_REG) }, { 0 } }
};
static const CGEN_IFMT ifmt_speed = {
16, 16, 0xff00, { { F (F_OP8) }, { F (F_IMM8) }, { 0 } }
};
static const CGEN_IFMT ifmt_ireadi = {
16, 16, 0xffff, { { F (F_OP6) }, { F (F_OP6_10LOW) }, { 0 } }
};
static const CGEN_IFMT ifmt_page = {
16, 16, 0xfff8, { { F (F_OP6) }, { F (F_OP6_7LOW) }, { F (F_PAGE3) }, { 0 } }
};
static const CGEN_IFMT ifmt_reti = {
16, 16, 0xfff8, { { F (F_OP6) }, { F (F_OP6_7LOW) }, { F (F_RETI3) }, { 0 } }
};
#undef F
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define A(a) (1 << CGEN_INSN_##a)
#else
#define A(a) (1 << CGEN_INSN_/**/a)
#endif
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define OPERAND(op) IP2K_OPERAND_##op
#else
#define OPERAND(op) IP2K_OPERAND_/**/op
#endif
#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
/* The instruction table. */
static const CGEN_OPCODE ip2k_cgen_insn_opcode_table[MAX_INSNS] =
{
/* Special null first entry.
A `num' value of zero is thus invalid.
Also, the special `invalid' insn resides here. */
{ { 0, 0, 0, 0 }, {{0}}, 0, {0}},
/* jmp $addr16cjp */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (ADDR16CJP), 0 } },
& ifmt_jmp, { 0xe000 }
},
/* call $addr16cjp */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (ADDR16CJP), 0 } },
& ifmt_jmp, { 0xc000 }
},
/* sb $fr,$bitno */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), ',', OP (BITNO), 0 } },
& ifmt_sb, { 0xb000 }
},
/* snb $fr,$bitno */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), ',', OP (BITNO), 0 } },
& ifmt_sb, { 0xa000 }
},
/* setb $fr,$bitno */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), ',', OP (BITNO), 0 } },
& ifmt_sb, { 0x9000 }
},
/* clrb $fr,$bitno */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), ',', OP (BITNO), 0 } },
& ifmt_sb, { 0x8000 }
},
/* xor W,#$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7f00 }
},
/* and W,#$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7e00 }
},
/* or W,#$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7d00 }
},
/* add W,#$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7b00 }
},
/* sub W,#$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7a00 }
},
/* cmp W,#$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7900 }
},
/* retw #$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7800 }
},
/* cse W,#$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7700 }
},
/* csne W,#$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7600 }
},
/* push #$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7400 }
},
/* muls W,#$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7300 }
},
/* mulu W,#$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7200 }
},
/* loadl #$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7100 }
},
/* loadh #$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7000 }
},
/* loadl $addr16l */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (ADDR16L), 0 } },
& ifmt_loadl_a, { 0x7100 }
},
/* loadh $addr16h */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (ADDR16H), 0 } },
& ifmt_loadh_a, { 0x7000 }
},
/* addc $fr,W */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), ',', 'W', 0 } },
& ifmt_addcfr_w, { 0x5e00 }
},
/* addc W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x5c00 }
},
/* incsnz $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x5a00 }
},
/* incsnz W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x5800 }
},
/* muls W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x5400 }
},
/* mulu W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x5000 }
},
/* decsnz $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x4e00 }
},
/* decsnz W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x4c00 }
},
/* subc W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x4800 }
},
/* subc $fr,W */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), ',', 'W', 0 } },
& ifmt_addcfr_w, { 0x4a00 }
},
/* pop $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x4600 }
},
/* push $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x4400 }
},
/* cse W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x4200 }
},
/* csne W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x4000 }
},
/* incsz $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x3e00 }
},
/* incsz W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x3c00 }
},
/* swap $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x3a00 }
},
/* swap W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x3800 }
},
/* rl $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x3600 }
},
/* rl W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x3400 }
},
/* rr $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x3200 }
},
/* rr W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x3000 }
},
/* decsz $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x2e00 }
},
/* decsz W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x2c00 }
},
/* inc $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x2a00 }
},
/* inc W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x2800 }
},
/* not $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x2600 }
},
/* not W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x2400 }
},
/* test $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x2200 }
},
/* mov W,#$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
& ifmt_xorw_l, { 0x7c00 }
},
/* mov $fr,W */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), ',', 'W', 0 } },
& ifmt_addcfr_w, { 0x200 }
},
/* mov W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x2000 }
},
/* add $fr,W */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), ',', 'W', 0 } },
& ifmt_addcfr_w, { 0x1e00 }
},
/* add W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x1c00 }
},
/* xor $fr,W */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), ',', 'W', 0 } },
& ifmt_addcfr_w, { 0x1a00 }
},
/* xor W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x1800 }
},
/* and $fr,W */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), ',', 'W', 0 } },
& ifmt_addcfr_w, { 0x1600 }
},
/* and W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x1400 }
},
/* or $fr,W */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), ',', 'W', 0 } },
& ifmt_addcfr_w, { 0x1200 }
},
/* or W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x1000 }
},
/* dec $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0xe00 }
},
/* dec W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0xc00 }
},
/* sub $fr,W */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), ',', 'W', 0 } },
& ifmt_addcfr_w, { 0xa00 }
},
/* sub W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x800 }
},
/* clr $fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x600 }
},
/* cmp W,$fr */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', 'W', ',', OP (FR), 0 } },
& ifmt_addcfr_w, { 0x400 }
},
/* speed #$lit8 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', '#', OP (LIT8), 0 } },
& ifmt_speed, { 0x100 }
},
/* ireadi */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x1d }
},
/* iwritei */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x1c }
},
/* fread */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x1b }
},
/* fwrite */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x1a }
},
/* iread */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x19 }
},
/* iwrite */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x18 }
},
/* page $addr16p */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (ADDR16P), 0 } },
& ifmt_page, { 0x10 }
},
/* system */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0xff }
},
/* reti #$reti3 */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', '#', OP (RETI3), 0 } },
& ifmt_reti, { 0x8 }
},
/* ret */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x7 }
},
/* int */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x6 }
},
/* breakx */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x5 }
},
/* cwdt */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x4 }
},
/* ferase */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x3 }
},
/* retnp */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x2 }
},
/* break */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x1 }
},
/* nop */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_ireadi, { 0x0 }
},
};
#undef A
#undef OPERAND
#undef MNEM
#undef OP
/* Formats for ALIAS macro-insns. */
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define F(f) & ip2k_cgen_ifld_table[IP2K_##f]
#else
#define F(f) & ip2k_cgen_ifld_table[IP2K_/**/f]
#endif
static const CGEN_IFMT ifmt_sc = {
16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
};
static const CGEN_IFMT ifmt_snc = {
16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
};
static const CGEN_IFMT ifmt_sz = {
16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
};
static const CGEN_IFMT ifmt_snz = {
16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
};
static const CGEN_IFMT ifmt_skip = {
16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
};
static const CGEN_IFMT ifmt_skipb = {
16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
};
#undef F
/* Each non-simple macro entry points to an array of expansion possibilities. */
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define A(a) (1 << CGEN_INSN_##a)
#else
#define A(a) (1 << CGEN_INSN_/**/a)
#endif
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define OPERAND(op) IP2K_OPERAND_##op
#else
#define OPERAND(op) IP2K_OPERAND_/**/op
#endif
#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
/* The macro instruction table. */
static const CGEN_IBASE ip2k_cgen_macro_insn_table[] =
{
/* sc */
{
-1, "sc", "sc", 16,
{ 0|A(ALIAS), { (1<<MACH_BASE) } }
},
/* snc */
{
-1, "snc", "snc", 16,
{ 0|A(ALIAS), { (1<<MACH_BASE) } }
},
/* sz */
{
-1, "sz", "sz", 16,
{ 0|A(ALIAS), { (1<<MACH_BASE) } }
},
/* snz */
{
-1, "snz", "snz", 16,
{ 0|A(ALIAS), { (1<<MACH_BASE) } }
},
/* skip */
{
-1, "skip", "skip", 16,
{ 0|A(SKIPA)|A(ALIAS), { (1<<MACH_BASE) } }
},
/* skip */
{
-1, "skipb", "skip", 16,
{ 0|A(SKIPA)|A(ALIAS), { (1<<MACH_BASE) } }
},
};
/* The macro instruction opcode table. */
static const CGEN_OPCODE ip2k_cgen_macro_insn_opcode_table[] =
{
/* sc */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_sc, { 0xb00b }
},
/* snc */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_snc, { 0xa00b }
},
/* sz */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_sz, { 0xb40b }
},
/* snz */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_snz, { 0xa40b }
},
/* skip */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_skip, { 0xa009 }
},
/* skip */
{
{ 0, 0, 0, 0 },
{ { MNEM, 0 } },
& ifmt_skipb, { 0xb009 }
},
};
#undef A
#undef OPERAND
#undef MNEM
#undef OP
#ifndef CGEN_ASM_HASH_P
#define CGEN_ASM_HASH_P(insn) 1
#endif
#ifndef CGEN_DIS_HASH_P
#define CGEN_DIS_HASH_P(insn) 1
#endif
/* Return non-zero if INSN is to be added to the hash table.
Targets are free to override CGEN_{ASM,DIS}_HASH_P in the .opc file. */
static int
asm_hash_insn_p (insn)
const CGEN_INSN *insn ATTRIBUTE_UNUSED;
{
return CGEN_ASM_HASH_P (insn);
}
static int
dis_hash_insn_p (insn)
const CGEN_INSN *insn;
{
/* If building the hash table and the NO-DIS attribute is present,
ignore. */
if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_NO_DIS))
return 0;
return CGEN_DIS_HASH_P (insn);
}
#ifndef CGEN_ASM_HASH
#define CGEN_ASM_HASH_SIZE 127
#ifdef CGEN_MNEMONIC_OPERANDS
#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE)
#else
#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) /*FIXME*/
#endif
#endif
/* It doesn't make much sense to provide a default here,
but while this is under development we do.
BUFFER is a pointer to the bytes of the insn, target order.
VALUE is the first base_insn_bitsize bits as an int in host order. */
#ifndef CGEN_DIS_HASH
#define CGEN_DIS_HASH_SIZE 256
#define CGEN_DIS_HASH(buf, value) (*(unsigned char *) (buf))
#endif
/* The result is the hash value of the insn.
Targets are free to override CGEN_{ASM,DIS}_HASH in the .opc file. */
static unsigned int
asm_hash_insn (mnem)
const char * mnem;
{
return CGEN_ASM_HASH (mnem);
}
/* BUF is a pointer to the bytes of the insn, target order.
VALUE is the first base_insn_bitsize bits as an int in host order. */
static unsigned int
dis_hash_insn (buf, value)
const char * buf ATTRIBUTE_UNUSED;
CGEN_INSN_INT value ATTRIBUTE_UNUSED;
{
return CGEN_DIS_HASH (buf, value);
}
static void set_fields_bitsize PARAMS ((CGEN_FIELDS *, int));
/* Set the recorded length of the insn in the CGEN_FIELDS struct. */
static void
set_fields_bitsize (fields, size)
CGEN_FIELDS *fields;
int size;
{
CGEN_FIELDS_BITSIZE (fields) = size;
}
/* Function to call before using the operand instance table.
This plugs the opcode entries and macro instructions into the cpu table. */
void
ip2k_cgen_init_opcode_table (cd)
CGEN_CPU_DESC cd;
{
int i;
int num_macros = (sizeof (ip2k_cgen_macro_insn_table) /
sizeof (ip2k_cgen_macro_insn_table[0]));
const CGEN_IBASE *ib = & ip2k_cgen_macro_insn_table[0];
const CGEN_OPCODE *oc = & ip2k_cgen_macro_insn_opcode_table[0];
CGEN_INSN *insns = (CGEN_INSN *) xmalloc (num_macros * sizeof (CGEN_INSN));
memset (insns, 0, num_macros * sizeof (CGEN_INSN));
for (i = 0; i < num_macros; ++i)
{
insns[i].base = &ib[i];
insns[i].opcode = &oc[i];
ip2k_cgen_build_insn_regex (& insns[i]);
}
cd->macro_insn_table.init_entries = insns;
cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE);
cd->macro_insn_table.num_init_entries = num_macros;
oc = & ip2k_cgen_insn_opcode_table[0];
insns = (CGEN_INSN *) cd->insn_table.init_entries;
for (i = 0; i < MAX_INSNS; ++i)
{
insns[i].opcode = &oc[i];
ip2k_cgen_build_insn_regex (& insns[i]);
}
cd->sizeof_fields = sizeof (CGEN_FIELDS);
cd->set_fields_bitsize = set_fields_bitsize;
cd->asm_hash_p = asm_hash_insn_p;
cd->asm_hash = asm_hash_insn;
cd->asm_hash_size = CGEN_ASM_HASH_SIZE;
cd->dis_hash_p = dis_hash_insn_p;
cd->dis_hash = dis_hash_insn;
cd->dis_hash_size = CGEN_DIS_HASH_SIZE;
}

133
opcodes/ip2k-opc.h Normal file
View File

@ -0,0 +1,133 @@
/* Instruction opcode header for ip2k.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef IP2K_OPC_H
#define IP2K_OPC_H
/* -- opc.h */
/* Check applicability of instructions against machines. */
#define CGEN_VALIDATE_INSN_SUPPORTED
/* Allows reason codes to be output when assembler errors occur. */
#define CGEN_VERBOSE_ASSEMBLER_ERRORS
/* Override disassembly hashing - there are variable bits in the top
byte of these instructions. */
#define CGEN_DIS_HASH_SIZE 8
#define CGEN_DIS_HASH(buf,value) (((* (unsigned char*) (buf)) >> 5) % CGEN_DIS_HASH_SIZE)
#define CGEN_ASM_HASH_SIZE 127
#define CGEN_ASM_HASH(insn) ip2k_asm_hash(insn)
extern unsigned int ip2k_asm_hash (const char *insn);
/* Special check to ensure that instruction exists for given machine. */
static int
ip2k_cgen_insn_supported (cd, insn)
CGEN_CPU_DESC cd;
CGEN_INSN *insn;
{
int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
/* No mach attribute? Assume it's supported for all machs. */
if (machs == 0)
return 1;
return ((machs & cd->machs) != 0);
}
/* -- opc.c */
/* Enum declaration for ip2k instruction types. */
typedef enum cgen_insn_type {
IP2K_INSN_INVALID, IP2K_INSN_JMP, IP2K_INSN_CALL, IP2K_INSN_SB
, IP2K_INSN_SNB, IP2K_INSN_SETB, IP2K_INSN_CLRB, IP2K_INSN_XORW_L
, IP2K_INSN_ANDW_L, IP2K_INSN_ORW_L, IP2K_INSN_ADDW_L, IP2K_INSN_SUBW_L
, IP2K_INSN_CMPW_L, IP2K_INSN_RETW_L, IP2K_INSN_CSEW_L, IP2K_INSN_CSNEW_L
, IP2K_INSN_PUSH_L, IP2K_INSN_MULSW_L, IP2K_INSN_MULUW_L, IP2K_INSN_LOADL_L
, IP2K_INSN_LOADH_L, IP2K_INSN_LOADL_A, IP2K_INSN_LOADH_A, IP2K_INSN_ADDCFR_W
, IP2K_INSN_ADDCW_FR, IP2K_INSN_INCSNZ_FR, IP2K_INSN_INCSNZW_FR, IP2K_INSN_MULSW_FR
, IP2K_INSN_MULUW_FR, IP2K_INSN_DECSNZ_FR, IP2K_INSN_DECSNZW_FR, IP2K_INSN_SUBCW_FR
, IP2K_INSN_SUBCFR_W, IP2K_INSN_POP_FR, IP2K_INSN_PUSH_FR, IP2K_INSN_CSEW_FR
, IP2K_INSN_CSNEW_FR, IP2K_INSN_INCSZ_FR, IP2K_INSN_INCSZW_FR, IP2K_INSN_SWAP_FR
, IP2K_INSN_SWAPW_FR, IP2K_INSN_RL_FR, IP2K_INSN_RLW_FR, IP2K_INSN_RR_FR
, IP2K_INSN_RRW_FR, IP2K_INSN_DECSZ_FR, IP2K_INSN_DECSZW_FR, IP2K_INSN_INC_FR
, IP2K_INSN_INCW_FR, IP2K_INSN_NOT_FR, IP2K_INSN_NOTW_FR, IP2K_INSN_TEST_FR
, IP2K_INSN_MOVW_L, IP2K_INSN_MOVFR_W, IP2K_INSN_MOVW_FR, IP2K_INSN_ADDFR_W
, IP2K_INSN_ADDW_FR, IP2K_INSN_XORFR_W, IP2K_INSN_XORW_FR, IP2K_INSN_ANDFR_W
, IP2K_INSN_ANDW_FR, IP2K_INSN_ORFR_W, IP2K_INSN_ORW_FR, IP2K_INSN_DEC_FR
, IP2K_INSN_DECW_FR, IP2K_INSN_SUBFR_W, IP2K_INSN_SUBW_FR, IP2K_INSN_CLR_FR
, IP2K_INSN_CMPW_FR, IP2K_INSN_SPEED, IP2K_INSN_IREADI, IP2K_INSN_IWRITEI
, IP2K_INSN_FREAD, IP2K_INSN_FWRITE, IP2K_INSN_IREAD, IP2K_INSN_IWRITE
, IP2K_INSN_PAGE, IP2K_INSN_SYSTEM, IP2K_INSN_RETI, IP2K_INSN_RET
, IP2K_INSN_INT, IP2K_INSN_BREAKX, IP2K_INSN_CWDT, IP2K_INSN_FERASE
, IP2K_INSN_RETNP, IP2K_INSN_BREAK, IP2K_INSN_NOP
} CGEN_INSN_TYPE;
/* Index of `invalid' insn place holder. */
#define CGEN_INSN_INVALID IP2K_INSN_INVALID
/* Total number of insns in table. */
#define MAX_INSNS ((int) IP2K_INSN_NOP + 1)
/* This struct records data prior to insertion or after extraction. */
struct cgen_fields
{
int length;
long f_nil;
long f_anyof;
long f_imm8;
long f_reg;
long f_addr16cjp;
long f_dir;
long f_bitno;
long f_op3;
long f_op4;
long f_op4mid;
long f_op6;
long f_op8;
long f_op6_10low;
long f_op6_7low;
long f_reti3;
long f_skipb;
long f_page3;
};
#define CGEN_INIT_PARSE(od) \
{\
}
#define CGEN_INIT_INSERT(od) \
{\
}
#define CGEN_INIT_EXTRACT(od) \
{\
}
#define CGEN_INIT_PRINT(od) \
{\
}
#endif /* IP2K_OPC_H */