Add IP2k GAS and OPCODES support.
This commit is contained in:
parent
ccaf4e0741
commit
a40cbfa3c9
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
436
gas/NEWS
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 *));
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
;;
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
@set I80386
|
||||
@set I860
|
||||
@set I960
|
||||
@set IP2K
|
||||
@set M32R
|
||||
@set M68HC11
|
||||
@set M680X0
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
@ -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*));
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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" ;;
|
||||
|
|
|
@ -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" ;;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
Loading…
Reference in New Issue