Add LM32 port.
This commit is contained in:
parent
0cd530490f
commit
84e94c9023
@ -1,3 +1,17 @@
|
||||
2008-12-23 Jon Beniston <jon@beniston.com>
|
||||
|
||||
* Makefile.am: Add LM32 object files and dependencies.
|
||||
* Makefile.in: Regenerate.
|
||||
* archures.c: Add LM32 architechiture info.
|
||||
* targets.c: Likewise.
|
||||
* reloc.c: Likewise.
|
||||
* bfd-in2.h: Regenerate.
|
||||
* config.bfd: Add LM32 targets.
|
||||
* configure.in: Likewise.
|
||||
* configure: Regenerate.
|
||||
* cpu-lm32.c: New file.
|
||||
* elf32-lm32.c: New file.
|
||||
|
||||
2008-12-23 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/7036
|
||||
|
@ -83,6 +83,7 @@ ALL_MACHINES = \
|
||||
cpu-i960.lo \
|
||||
cpu-ip2k.lo \
|
||||
cpu-iq2000.lo \
|
||||
cpu-lm32.lo \
|
||||
cpu-m32c.lo \
|
||||
cpu-m32r.lo \
|
||||
cpu-m68hc11.lo \
|
||||
@ -149,6 +150,7 @@ ALL_MACHINES_CFILES = \
|
||||
cpu-i960.c \
|
||||
cpu-ip2k.c \
|
||||
cpu-iq2000.c \
|
||||
cpu-lm32.c \
|
||||
cpu-m32c.c \
|
||||
cpu-m32r.c \
|
||||
cpu-m68hc11.c \
|
||||
@ -264,6 +266,7 @@ BFD32_BACKENDS = \
|
||||
elf32-i960.lo \
|
||||
elf32-ip2k.lo \
|
||||
elf32-iq2000.lo \
|
||||
elf32-lm32.lo \
|
||||
elf32-m32c.lo \
|
||||
elf32-m32r.lo \
|
||||
elf32-m68hc11.lo \
|
||||
@ -445,6 +448,7 @@ BFD32_BACKENDS_CFILES = \
|
||||
elf32-i960.c \
|
||||
elf32-ip2k.c \
|
||||
elf32-iq2000.c \
|
||||
elf32-lm32.c \
|
||||
elf32-m32c.c \
|
||||
elf32-m32r.c \
|
||||
elf32-m68k.c \
|
||||
@ -1093,6 +1097,7 @@ cpu-i860.lo: cpu-i860.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-i960.lo: cpu-i960.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-ip2k.lo: cpu-ip2k.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-iq2000.lo: cpu-iq2000.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-lm32.lo: cpu-lm32.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-m32c.lo: cpu-m32c.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-m32r.lo: cpu-m32r.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-m68hc11.lo: cpu-m68hc11.c $(INCDIR)/filenames.h \
|
||||
@ -1426,6 +1431,10 @@ elf32-m32c.lo: elf32-m32c.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
|
||||
$(INCDIR)/elf/internal.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/m32c.h \
|
||||
$(INCDIR)/elf/reloc-macros.h $(INCDIR)/libiberty.h \
|
||||
elf32-target.h
|
||||
elf32-lm32.lo: elf32-lm32.c $(INCDIR)/filenames.h elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
|
||||
$(INCDIR)/bfdlink.h $(INCDIR)/elf/lm32.h $(INCDIR)/elf/reloc-macros.h \
|
||||
elf32-target.h
|
||||
elf32-m32r.lo: elf32-m32r.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
|
||||
elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/external.h \
|
||||
$(INCDIR)/elf/internal.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/m32r.h \
|
||||
|
@ -348,6 +348,7 @@ ALL_MACHINES = \
|
||||
cpu-i960.lo \
|
||||
cpu-ip2k.lo \
|
||||
cpu-iq2000.lo \
|
||||
cpu-lm32.lo \
|
||||
cpu-m32c.lo \
|
||||
cpu-m32r.lo \
|
||||
cpu-m68hc11.lo \
|
||||
@ -414,6 +415,7 @@ ALL_MACHINES_CFILES = \
|
||||
cpu-i960.c \
|
||||
cpu-ip2k.c \
|
||||
cpu-iq2000.c \
|
||||
cpu-lm32.c \
|
||||
cpu-m32c.c \
|
||||
cpu-m32r.c \
|
||||
cpu-m68hc11.c \
|
||||
@ -530,6 +532,7 @@ BFD32_BACKENDS = \
|
||||
elf32-i960.lo \
|
||||
elf32-ip2k.lo \
|
||||
elf32-iq2000.lo \
|
||||
elf32-lm32.lo \
|
||||
elf32-m32c.lo \
|
||||
elf32-m32r.lo \
|
||||
elf32-m68hc11.lo \
|
||||
@ -711,6 +714,7 @@ BFD32_BACKENDS_CFILES = \
|
||||
elf32-i960.c \
|
||||
elf32-ip2k.c \
|
||||
elf32-iq2000.c \
|
||||
elf32-lm32.c \
|
||||
elf32-m32c.c \
|
||||
elf32-m32r.c \
|
||||
elf32-m68k.c \
|
||||
@ -1689,6 +1693,7 @@ cpu-i860.lo: cpu-i860.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-i960.lo: cpu-i960.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-ip2k.lo: cpu-ip2k.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-iq2000.lo: cpu-iq2000.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-lm32.lo: cpu-lm32.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-m32c.lo: cpu-m32c.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-m32r.lo: cpu-m32r.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
|
||||
cpu-m68hc11.lo: cpu-m68hc11.c $(INCDIR)/filenames.h \
|
||||
@ -2017,6 +2022,10 @@ elf32-iq2000.lo: elf32-iq2000.c $(INCDIR)/filenames.h \
|
||||
$(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h $(INCDIR)/bfdlink.h \
|
||||
$(INCDIR)/elf/iq2000.h $(INCDIR)/elf/reloc-macros.h \
|
||||
elf32-target.h
|
||||
elf32-lm32.lo: elf32-lm32.c $(INCDIR)/filenames.h elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
|
||||
$(INCDIR)/bfdlink.h $(INCDIR)/elf/lm32.h $(INCDIR)/elf/reloc-macros.h \
|
||||
elf32-target.h
|
||||
elf32-m32c.lo: elf32-m32c.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
|
||||
elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/external.h \
|
||||
$(INCDIR)/elf/internal.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/m32c.h \
|
||||
|
@ -409,6 +409,8 @@ DESCRIPTION
|
||||
.#define bfd_mach_z80 3 {* With ixl, ixh, iyl, and iyh. *}
|
||||
.#define bfd_mach_z80full 7 {* All undocumented instructions. *}
|
||||
.#define bfd_mach_r800 11 {* R800: successor with multiplication. *}
|
||||
. bfd_arch_lm32, {* Lattice Mico32 *}
|
||||
.#define bfd_mach_lm32 1
|
||||
. bfd_arch_last
|
||||
. };
|
||||
*/
|
||||
@ -471,6 +473,7 @@ extern const bfd_arch_info_type bfd_i960_arch;
|
||||
extern const bfd_arch_info_type bfd_ia64_arch;
|
||||
extern const bfd_arch_info_type bfd_ip2k_arch;
|
||||
extern const bfd_arch_info_type bfd_iq2000_arch;
|
||||
extern const bfd_arch_info_type bfd_lm32_arch;
|
||||
extern const bfd_arch_info_type bfd_m32c_arch;
|
||||
extern const bfd_arch_info_type bfd_m32r_arch;
|
||||
extern const bfd_arch_info_type bfd_m68hc11_arch;
|
||||
@ -542,6 +545,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] =
|
||||
&bfd_ia64_arch,
|
||||
&bfd_ip2k_arch,
|
||||
&bfd_iq2000_arch,
|
||||
&bfd_lm32_arch,
|
||||
&bfd_m32c_arch,
|
||||
&bfd_m32r_arch,
|
||||
&bfd_m68hc11_arch,
|
||||
|
@ -2035,6 +2035,8 @@ enum bfd_architecture
|
||||
#define bfd_mach_z80 3 /* With ixl, ixh, iyl, and iyh. */
|
||||
#define bfd_mach_z80full 7 /* All undocumented instructions. */
|
||||
#define bfd_mach_r800 11 /* R800: successor with multiplication. */
|
||||
bfd_arch_lm32, /* Lattice Mico32 */
|
||||
#define bfd_mach_lm32 1
|
||||
bfd_arch_last
|
||||
};
|
||||
|
||||
@ -4412,6 +4414,17 @@ BFD_RELOC_XTENSA_ASM_EXPAND. */
|
||||
|
||||
/* 4 bit value. */
|
||||
BFD_RELOC_Z8K_IMM4L,
|
||||
|
||||
/* Lattice Mico32 relocations. */
|
||||
BFD_RELOC_LM32_CALL,
|
||||
BFD_RELOC_LM32_BRANCH,
|
||||
BFD_RELOC_LM32_16_GOT,
|
||||
BFD_RELOC_LM32_GOTOFF_HI16,
|
||||
BFD_RELOC_LM32_GOTOFF_LO16,
|
||||
BFD_RELOC_LM32_COPY,
|
||||
BFD_RELOC_LM32_GLOB_DAT,
|
||||
BFD_RELOC_LM32_JMP_SLOT,
|
||||
BFD_RELOC_LM32_RELATIVE,
|
||||
BFD_RELOC_UNUSED };
|
||||
typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
|
||||
reloc_howto_type *bfd_reloc_type_lookup
|
||||
|
@ -85,6 +85,7 @@ fido*) targ_archs=bfd_m68k_arch ;;
|
||||
hppa*) targ_archs=bfd_hppa_arch ;;
|
||||
i[3-7]86) targ_archs=bfd_i386_arch ;;
|
||||
i370) targ_archs=bfd_i370_arch ;;
|
||||
lm32) targ_archs=bfd_lm32_arch ;;
|
||||
m6811*|m68hc11*) targ_archs="bfd_m68hc11_arch bfd_m68hc12_arch" ;;
|
||||
m6812*|m68hc12*) targ_archs="bfd_m68hc12_arch bfd_m68hc11_arch" ;;
|
||||
m68*) targ_archs=bfd_m68k_arch ;;
|
||||
@ -727,6 +728,16 @@ case "${targ}" in
|
||||
targ_defvec=bfd_elf32_iq2000_vec
|
||||
;;
|
||||
|
||||
lm32-*-elf)
|
||||
targ_defvec=bfd_elf32_lm32_vec
|
||||
targ_selvecs=bfd_elf32_lm32fdpic_vec
|
||||
;;
|
||||
|
||||
lm32-*-*linux*)
|
||||
targ_defvec=bfd_elf32_lm32fdpic_vec
|
||||
targ_selvecs=bfd_elf32_lm32_vec
|
||||
;;
|
||||
|
||||
m32c-*-elf | m32c-*-rtems*)
|
||||
targ_defvec=bfd_elf32_m32c_vec
|
||||
;;
|
||||
|
2
bfd/configure
vendored
2
bfd/configure
vendored
@ -20752,6 +20752,8 @@ do
|
||||
bfd_elf32_ia64_hpux_big_vec) tb="$tb elf32-ia64.lo elf32.lo $elf";;
|
||||
bfd_elf32_ip2k_vec) tb="$tb elf32-ip2k.lo elf32.lo $elf" ;;
|
||||
bfd_elf32_iq2000_vec) tb="$tb elf32-iq2000.lo elf32.lo $elf" ;;
|
||||
bfd_elf32_lm32_vec) tb="$tb elf32-lm32.lo elf32.lo $elf" ;;
|
||||
bfd_elf32_lm32fdpic_vec) tb="$tb elf32-lm32.lo elf32.lo $elf" ;;
|
||||
bfd_elf32_little_generic_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
|
||||
bfd_elf32_littlearc_vec) tb="$tb elf32-arc.lo elf32.lo $elf" ;;
|
||||
bfd_elf32_littlearm_symbian_vec)
|
||||
|
@ -689,6 +689,8 @@ do
|
||||
bfd_elf32_ia64_hpux_big_vec) tb="$tb elf32-ia64.lo elf32.lo $elf";;
|
||||
bfd_elf32_ip2k_vec) tb="$tb elf32-ip2k.lo elf32.lo $elf" ;;
|
||||
bfd_elf32_iq2000_vec) tb="$tb elf32-iq2000.lo elf32.lo $elf" ;;
|
||||
bfd_elf32_lm32_vec) tb="$tb elf32-lm32.lo elf32.lo $elf" ;;
|
||||
bfd_elf32_lm32fdpic_vec) tb="$tb elf32-lm32.lo elf32.lo $elf" ;;
|
||||
bfd_elf32_little_generic_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
|
||||
bfd_elf32_littlearc_vec) tb="$tb elf32-arc.lo elf32.lo $elf" ;;
|
||||
bfd_elf32_littlearm_symbian_vec)
|
||||
|
41
bfd/cpu-lm32.c
Normal file
41
bfd/cpu-lm32.c
Normal file
@ -0,0 +1,41 @@
|
||||
/* BFD support for the Lattice Mico32 architecture.
|
||||
Copyright 2008 Free Software Foundation, Inc.
|
||||
Contributed by Jon Beniston <jon@beniston.com>
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
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 3 of the License, 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., 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
const bfd_arch_info_type bfd_lm32_arch =
|
||||
{
|
||||
32, /* Bits in word. */
|
||||
32, /* Bits in address. */
|
||||
8, /* Bits in byte. */
|
||||
bfd_arch_lm32, /* Enum bfd_architecture. */
|
||||
bfd_mach_lm32, /* Machine number. */
|
||||
"lm32", /* Architecture name. */
|
||||
"lm32", /* Printable name. */
|
||||
4, /* Alignment. */
|
||||
TRUE, /* Is this the default machine for the target. */
|
||||
bfd_default_compatible, /* Function callback to test if two files have compatible machines. */
|
||||
bfd_default_scan,
|
||||
NULL /* Next. */
|
||||
};
|
||||
|
2909
bfd/elf32-lm32.c
Normal file
2909
bfd/elf32-lm32.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -2027,6 +2027,15 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
||||
"BFD_RELOC_Z8K_DISP7",
|
||||
"BFD_RELOC_Z8K_CALLR",
|
||||
"BFD_RELOC_Z8K_IMM4L",
|
||||
"BFD_RELOC_LM32_CALL",
|
||||
"BFD_RELOC_LM32_BRANCH",
|
||||
"BFD_RELOC_LM32_16_GOT",
|
||||
"BFD_RELOC_LM32_GOTOFF_HI16",
|
||||
"BFD_RELOC_LM32_GOTOFF_LO16",
|
||||
"BFD_RELOC_LM32_COPY",
|
||||
"BFD_RELOC_LM32_GLOB_DAT",
|
||||
"BFD_RELOC_LM32_JMP_SLOT",
|
||||
"BFD_RELOC_LM32_RELATIVE",
|
||||
"@@overflow: BFD_RELOC_UNUSED@@",
|
||||
};
|
||||
#endif
|
||||
|
21
bfd/reloc.c
21
bfd/reloc.c
@ -5083,6 +5083,27 @@ ENUM
|
||||
ENUMDOC
|
||||
4 bit value.
|
||||
|
||||
ENUM
|
||||
BFD_RELOC_LM32_CALL
|
||||
ENUMX
|
||||
BFD_RELOC_LM32_BRANCH
|
||||
ENUMX
|
||||
BFD_RELOC_LM32_16_GOT
|
||||
ENUMX
|
||||
BFD_RELOC_LM32_GOTOFF_HI16
|
||||
ENUMX
|
||||
BFD_RELOC_LM32_GOTOFF_LO16
|
||||
ENUMX
|
||||
BFD_RELOC_LM32_COPY
|
||||
ENUMX
|
||||
BFD_RELOC_LM32_GLOB_DAT
|
||||
ENUMX
|
||||
BFD_RELOC_LM32_JMP_SLOT
|
||||
ENUMX
|
||||
BFD_RELOC_LM32_RELATIVE
|
||||
ENUMDOC
|
||||
Lattice Mico32 relocations.
|
||||
|
||||
ENDSENUM
|
||||
BFD_RELOC_UNUSED
|
||||
CODE_FRAGMENT
|
||||
|
@ -604,6 +604,8 @@ extern const bfd_target bfd_elf32_ia64_big_vec;
|
||||
extern const bfd_target bfd_elf32_ia64_hpux_big_vec;
|
||||
extern const bfd_target bfd_elf32_ip2k_vec;
|
||||
extern const bfd_target bfd_elf32_iq2000_vec;
|
||||
extern const bfd_target bfd_elf32_lm32_vec;
|
||||
extern const bfd_target bfd_elf32_lm32fdpic_vec;
|
||||
extern const bfd_target bfd_elf32_little_generic_vec;
|
||||
extern const bfd_target bfd_elf32_littlearc_vec;
|
||||
extern const bfd_target bfd_elf32_littlearm_vec;
|
||||
@ -939,6 +941,7 @@ static const bfd_target * const _bfd_target_vector[] =
|
||||
#endif
|
||||
&bfd_elf32_ip2k_vec,
|
||||
&bfd_elf32_iq2000_vec,
|
||||
&bfd_elf32_lm32_vec,
|
||||
&bfd_elf32_little_generic_vec,
|
||||
&bfd_elf32_littlearc_vec,
|
||||
&bfd_elf32_littlearm_vec,
|
||||
|
@ -1,3 +1,8 @@
|
||||
2008-12-23 Jon Beniston <jon@beniston.com>
|
||||
|
||||
* MAINTAINERS: Added Jon Beniston as maintainer for LM32 port.
|
||||
* readelf.c: Add support for LM32 machine number.
|
||||
|
||||
2008-12-23 Kai Tietz <kai.tietz@onevision.com>
|
||||
|
||||
* rcparse.y (rcdata_data): Allow empty comma elements.
|
||||
|
@ -85,6 +85,7 @@ responsibility among the other maintainers.
|
||||
ix86 PE Christopher Faylor <me+binutils@cgf.cx>
|
||||
ix86 COFF DJ Delorie <dj@redhat.com>
|
||||
ix86 INTEL MODE Jan Beulich <jbeulich@novell.com>
|
||||
LM32 Jon Beniston <jon@beniston.com>
|
||||
M68HC11 M68HC12 Stephane Carrez <stcarrez@nerim.fr>
|
||||
M88k Mark Kettenis <kettenis@gnu.org>
|
||||
MAXQ Inderpreet Singh <inderpreetb@noida.hcltech.com>
|
||||
|
@ -130,6 +130,7 @@
|
||||
#include "elf/i960.h"
|
||||
#include "elf/ia64.h"
|
||||
#include "elf/ip2k.h"
|
||||
#include "elf/lm32.h"
|
||||
#include "elf/iq2000.h"
|
||||
#include "elf/m32c.h"
|
||||
#include "elf/m32r.h"
|
||||
@ -598,6 +599,7 @@ guess_is_rela (unsigned int e_machine)
|
||||
case EM_IP2K:
|
||||
case EM_IP2K_OLD:
|
||||
case EM_IQ2000:
|
||||
case EM_LATTICEMICO32:
|
||||
case EM_M32C_OLD:
|
||||
case EM_M32C:
|
||||
case EM_M32R:
|
||||
@ -1186,6 +1188,10 @@ dump_relocations (FILE *file,
|
||||
rtype = elf_xtensa_reloc_type (type);
|
||||
break;
|
||||
|
||||
case EM_LATTICEMICO32:
|
||||
rtype = elf_lm32_reloc_type (type);
|
||||
break;
|
||||
|
||||
case EM_M32C_OLD:
|
||||
case EM_M32C:
|
||||
rtype = elf_m32c_reloc_type (type);
|
||||
@ -1833,6 +1839,7 @@ get_machine_name (unsigned e_machine)
|
||||
case EM_IQ2000: return "Vitesse IQ2000";
|
||||
case EM_XTENSA_OLD:
|
||||
case EM_XTENSA: return "Tensilica Xtensa Processor";
|
||||
case EM_LATTICEMICO32: return "Lattice Mico32";
|
||||
case EM_M32C_OLD:
|
||||
case EM_M32C: return "Renesas M32c";
|
||||
case EM_MT: return "Morpho Techologies MT processor";
|
||||
@ -8082,6 +8089,8 @@ is_32bit_abs_reloc (unsigned int reloc_type)
|
||||
return reloc_type == 2; /* R_IP2K_32. */
|
||||
case EM_IQ2000:
|
||||
return reloc_type == 2; /* R_IQ2000_32. */
|
||||
case EM_LATTICEMICO32:
|
||||
return reloc_type == 3; /* R_LM32_32. */
|
||||
case EM_M32C_OLD:
|
||||
case EM_M32C:
|
||||
return reloc_type == 3; /* R_M32C_32. */
|
||||
|
@ -1,3 +1,8 @@
|
||||
2008-12-23 Jon Beniston <jon@beniston.com>
|
||||
|
||||
* lm32.cpu: New file.
|
||||
* lm32.opc: New file.
|
||||
|
||||
2008-01-29 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* mt.opc (parse_imm16): Apply 2007-09-26 opcodes/mt-asm.c change
|
||||
|
932
cpu/lm32.cpu
Normal file
932
cpu/lm32.cpu
Normal file
@ -0,0 +1,932 @@
|
||||
; Lattice Mico32 CPU description. -*- Scheme -*-
|
||||
; Copyright 2008 Free Software Foundation, Inc.
|
||||
; Contributed by Jon Beniston <jon@beniston.com>
|
||||
;
|
||||
; This file is part of the GNU Binutils.
|
||||
;
|
||||
; 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 3 of the License, 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., 51 Franklin Street - Fifth Floor, Boston,
|
||||
; MA 02110-1301, USA.
|
||||
|
||||
(include "simplify.inc")
|
||||
|
||||
(define-arch
|
||||
(name lm32) ; name of cpu family
|
||||
(comment "Lattice Mico32")
|
||||
(default-alignment aligned)
|
||||
(insn-lsb0? #t)
|
||||
(machs lm32)
|
||||
(isas lm32)
|
||||
)
|
||||
|
||||
|
||||
; Instruction sets.
|
||||
|
||||
(define-isa
|
||||
(name lm32)
|
||||
(comment "Lattice Mico32 ISA")
|
||||
(default-insn-word-bitsize 32)
|
||||
(default-insn-bitsize 32)
|
||||
(base-insn-bitsize 32)
|
||||
(decode-assist (31 30 29 28 27 26))
|
||||
)
|
||||
|
||||
|
||||
; Cpu family definitions.
|
||||
|
||||
(define-cpu
|
||||
; cpu names must be distinct from the architecture name and machine name
|
||||
(name lm32bf)
|
||||
(comment "Lattice Mico32 CPU")
|
||||
(endian big)
|
||||
(word-bitsize 32)
|
||||
)
|
||||
|
||||
(define-mach
|
||||
(name lm32)
|
||||
(comment "Lattice Mico32 MACH")
|
||||
(cpu lm32bf)
|
||||
)
|
||||
|
||||
(define-model
|
||||
(name lm32)
|
||||
(comment "Lattice Mico32 reference implementation")
|
||||
(mach lm32)
|
||||
(unit u-exec "Execution unit" ()
|
||||
1 1 () () () ())
|
||||
)
|
||||
|
||||
|
||||
; Hardware elements.
|
||||
|
||||
(dnh h-pc "Program counter" (PC) (pc) () () ())
|
||||
|
||||
(dnh h-gr "General purpose registers"
|
||||
()
|
||||
(register SI (32))
|
||||
(keyword "" (
|
||||
(gp 26) (fp 27) (sp 28) (ra 29) (ea 30) (ba 31)
|
||||
(r0 0) (r1 1) (r2 2) (r3 3)
|
||||
(r4 4) (r5 5) (r6 6) (r7 7)
|
||||
(r8 8) (r9 9) (r10 10) (r11 11)
|
||||
(r12 12) (r13 13) (r14 14) (r15 15)
|
||||
(r16 16) (r17 17) (r18 18) (r19 19)
|
||||
(r20 20) (r21 21) (r22 22) (r23 23)
|
||||
(r24 24) (r25 25) (r26 26) (r27 27)
|
||||
(r28 28) (r29 29) (r30 30) (r31 31)
|
||||
)
|
||||
)
|
||||
() ()
|
||||
)
|
||||
|
||||
(dnh h-csr "Control and status registers"
|
||||
()
|
||||
(register SI (32))
|
||||
(keyword "" (
|
||||
(IE 0) (IM 1) (IP 2)
|
||||
(ICC 3) (DCC 4)
|
||||
(CC 5)
|
||||
(CFG 6)
|
||||
(EBA 7)
|
||||
(DC 8)
|
||||
(DEBA 9)
|
||||
(JTX 14) (JRX 15)
|
||||
(BP0 16) (BP1 17) (BP2 18) (BP3 19)
|
||||
(WP0 24) (WP1 25) (WP2 26) (WP3 27)
|
||||
)
|
||||
)
|
||||
() ()
|
||||
)
|
||||
|
||||
|
||||
; Instruction fields.
|
||||
|
||||
(dnf f-opcode "opcode field" () 31 6)
|
||||
(dnf f-r0 "register index 0 field" () 25 5)
|
||||
(dnf f-r1 "register index 1 field" () 20 5)
|
||||
(dnf f-r2 "register index 2 field" () 15 5)
|
||||
(dnf f-resv0 "reserved" (RESERVED) 10 11)
|
||||
(dnf f-shift "shift amount field" () 4 5)
|
||||
(df f-imm "signed immediate field" () 15 16 INT #f #f)
|
||||
(dnf f-uimm "unsigned immediate field" () 15 16)
|
||||
(dnf f-csr "csr field" () 25 5)
|
||||
(dnf f-user "user defined field" () 10 11)
|
||||
(dnf f-exception "exception field" () 25 26)
|
||||
|
||||
(df f-branch "branch offset field" (PCREL-ADDR) 15 16 INT
|
||||
((value pc) (sra SI (sub SI value pc) 2))
|
||||
((value pc) (add SI pc (sra SI (sll SI value 16) 14)))
|
||||
)
|
||||
(df f-call "call offset field" (PCREL-ADDR) 25 26 INT
|
||||
((value pc) (sra SI (sub SI value pc) 2))
|
||||
((value pc) (add SI pc (sra SI (sll SI value 6) 4)))
|
||||
)
|
||||
|
||||
|
||||
; Operands.
|
||||
|
||||
(dnop r0 "register 0" () h-gr f-r0)
|
||||
(dnop r1 "register 1" () h-gr f-r1)
|
||||
(dnop r2 "register 2" () h-gr f-r2)
|
||||
(dnop shift "shift amout" () h-uint f-shift)
|
||||
(dnop imm "signed immediate" () h-sint f-imm)
|
||||
(dnop uimm "unsigned immediate" () h-uint f-uimm)
|
||||
(dnop branch "branch offset" () h-iaddr f-branch)
|
||||
(dnop call "call offset" () h-iaddr f-call)
|
||||
(dnop csr "csr" () h-csr f-csr)
|
||||
(dnop user "user" () h-uint f-user)
|
||||
(dnop exception "exception" () h-uint f-exception)
|
||||
|
||||
(define-operand
|
||||
(name hi16)
|
||||
(comment "high 16-bit immediate")
|
||||
(attrs)
|
||||
(type h-uint)
|
||||
(index f-uimm)
|
||||
(handlers (parse "hi16"))
|
||||
)
|
||||
|
||||
(define-operand
|
||||
(name lo16)
|
||||
(comment "low 16-bit immediate")
|
||||
(attrs)
|
||||
(type h-uint)
|
||||
(index f-uimm)
|
||||
(handlers (parse "lo16"))
|
||||
)
|
||||
|
||||
(define-operand
|
||||
(name gp16)
|
||||
(comment "gp relative 16-bit immediate")
|
||||
(attrs)
|
||||
(type h-sint)
|
||||
(index f-imm)
|
||||
(handlers (parse "gp16"))
|
||||
)
|
||||
|
||||
(define-operand
|
||||
(name got16)
|
||||
(comment "got 16-bit immediate")
|
||||
(attrs)
|
||||
(type h-sint)
|
||||
(index f-imm)
|
||||
(handlers (parse "got16"))
|
||||
)
|
||||
|
||||
(define-operand
|
||||
(name gotoffhi16)
|
||||
(comment "got offset high 16-bit immediate")
|
||||
(attrs)
|
||||
(type h-sint)
|
||||
(index f-imm)
|
||||
(handlers (parse "gotoff_hi16"))
|
||||
)
|
||||
|
||||
(define-operand
|
||||
(name gotofflo16)
|
||||
(comment "got offset low 16-bit immediate")
|
||||
(attrs)
|
||||
(type h-sint)
|
||||
(index f-imm)
|
||||
(handlers (parse "gotoff_lo16"))
|
||||
)
|
||||
|
||||
|
||||
; Enumerations.
|
||||
|
||||
(define-normal-insn-enum
|
||||
opcodes "opcodes" () OP_ f-opcode
|
||||
(("ADD" 45)
|
||||
("ADDI" 13)
|
||||
("AND" 40)
|
||||
("ANDI" 8)
|
||||
("ANDHI" 24)
|
||||
("B" 48)
|
||||
("BI" 56)
|
||||
("BE" 17)
|
||||
("BG" 18)
|
||||
("BGE" 19)
|
||||
("BGEU" 20)
|
||||
("BGU" 21)
|
||||
("BNE" 23)
|
||||
("CALL" 54)
|
||||
("CALLI" 62)
|
||||
("CMPE" 57)
|
||||
("CMPEI" 25)
|
||||
("CMPG" 58)
|
||||
("CMPGI" 26)
|
||||
("CMPGE" 59)
|
||||
("CMPGEI" 27)
|
||||
("CMPGEU" 60)
|
||||
("CMPGEUI" 28)
|
||||
("CMPGU" 61)
|
||||
("CMPGUI" 29)
|
||||
("CMPNE" 63)
|
||||
("CMPNEI" 31)
|
||||
("DIVU" 35)
|
||||
("LB" 4)
|
||||
("LBU" 16)
|
||||
("LH" 7)
|
||||
("LHU" 11)
|
||||
("LW" 10)
|
||||
("MODU" 49)
|
||||
("MUL" 34)
|
||||
("MULI" 2)
|
||||
("NOR" 33)
|
||||
("NORI" 1)
|
||||
("OR" 46)
|
||||
("ORI" 14)
|
||||
("ORHI" 30)
|
||||
("RAISE" 43)
|
||||
("RCSR" 36)
|
||||
("SB" 12)
|
||||
("SEXTB" 44)
|
||||
("SEXTH" 55)
|
||||
("SH" 3)
|
||||
("SL" 47)
|
||||
("SLI" 15)
|
||||
("SR" 37)
|
||||
("SRI" 5)
|
||||
("SRU" 32)
|
||||
("SRUI" 0)
|
||||
("SUB" 50)
|
||||
("SW" 22)
|
||||
("USER" 51)
|
||||
("WCSR" 52)
|
||||
("XNOR" 41)
|
||||
("XNORI" 9)
|
||||
("XOR" 38)
|
||||
("XORI" 6)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
; Instructions. Note: Reg-reg must come before reg-imm.
|
||||
|
||||
(dni add "add" ()
|
||||
"add $r2,$r0,$r1"
|
||||
(+ OP_ADD r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (add r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni addi "add immediate" ()
|
||||
"addi $r1,$r0,$imm"
|
||||
(+ OP_ADDI r0 r1 imm)
|
||||
(set r1 (add r0 (ext SI (trunc HI imm))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni and "and" ()
|
||||
"and $r2,$r0,$r1"
|
||||
(+ OP_AND r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (and r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni andi "and immediate" ()
|
||||
"andi $r1,$r0,$uimm"
|
||||
(+ OP_ANDI r0 r1 uimm)
|
||||
(set r1 (and r0 (zext SI uimm)))
|
||||
()
|
||||
)
|
||||
|
||||
(dni andhii "and high immediate" ()
|
||||
"andhi $r1,$r0,$hi16"
|
||||
(+ OP_ANDHI r0 r1 hi16)
|
||||
(set r1 (and r0 (sll SI hi16 16)))
|
||||
()
|
||||
)
|
||||
|
||||
(dni b "branch" ()
|
||||
"b $r0"
|
||||
(+ OP_B r0 (f-r1 0) (f-r2 0) (f-resv0 0))
|
||||
(set pc (c-call USI "@cpu@_b_insn" r0 f-r0))
|
||||
()
|
||||
)
|
||||
|
||||
(dni bi "branch immediate" ()
|
||||
"bi $call"
|
||||
(+ OP_BI call)
|
||||
(set pc (ext SI call))
|
||||
()
|
||||
)
|
||||
|
||||
(dni be "branch equal" ()
|
||||
"be $r0,$r1,$branch"
|
||||
(+ OP_BE r0 r1 branch)
|
||||
(if (eq r0 r1)
|
||||
(set pc branch)
|
||||
)
|
||||
()
|
||||
)
|
||||
|
||||
(dni bg "branch greater" ()
|
||||
"bg $r0,$r1,$branch"
|
||||
(+ OP_BG r0 r1 branch)
|
||||
(if (gt r0 r1)
|
||||
(set pc branch)
|
||||
)
|
||||
()
|
||||
)
|
||||
|
||||
(dni bge "branch greater or equal" ()
|
||||
"bge $r0,$r1,$branch"
|
||||
(+ OP_BGE r0 r1 branch)
|
||||
(if (ge r0 r1)
|
||||
(set pc branch)
|
||||
)
|
||||
()
|
||||
)
|
||||
|
||||
(dni bgeu "branch greater or equal unsigned" ()
|
||||
"bgeu $r0,$r1,$branch"
|
||||
(+ OP_BGEU r0 r1 branch)
|
||||
(if (geu r0 r1)
|
||||
(set pc branch)
|
||||
)
|
||||
()
|
||||
)
|
||||
|
||||
(dni bgu "branch greater unsigned" ()
|
||||
"bgu $r0,$r1,$branch"
|
||||
(+ OP_BGU r0 r1 branch)
|
||||
(if (gtu r0 r1)
|
||||
(set pc branch)
|
||||
)
|
||||
()
|
||||
)
|
||||
|
||||
(dni bne "branch not equal" ()
|
||||
"bne $r0,$r1,$branch"
|
||||
(+ OP_BNE r0 r1 branch)
|
||||
(if (ne r0 r1)
|
||||
(set pc branch)
|
||||
)
|
||||
()
|
||||
)
|
||||
|
||||
(dni call "call" ()
|
||||
"call $r0"
|
||||
(+ OP_CALL r0 (f-r1 0) (f-r2 0) (f-resv0 0))
|
||||
(sequence ()
|
||||
(set (reg h-gr 29) (add pc 4))
|
||||
(set pc r0)
|
||||
)
|
||||
()
|
||||
)
|
||||
|
||||
(dni calli "call immediate" ()
|
||||
"calli $call"
|
||||
(+ OP_CALLI call)
|
||||
(sequence ()
|
||||
(set (reg h-gr 29) (add pc 4))
|
||||
(set pc (ext SI call))
|
||||
)
|
||||
()
|
||||
)
|
||||
|
||||
(dni cmpe "compare equal" ()
|
||||
"cmpe $r2,$r0,$r1"
|
||||
(+ OP_CMPE r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (eq SI r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni cmpei "compare equal immediate" ()
|
||||
"cmpei $r1,$r0,$imm"
|
||||
(+ OP_CMPEI r0 r1 imm)
|
||||
(set r1 (eq SI r0 (ext SI (trunc HI imm))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni cmpg "compare greater than" ()
|
||||
"cmpg $r2,$r0,$r1"
|
||||
(+ OP_CMPG r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (gt SI r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni cmpgi "compare greater than immediate" ()
|
||||
"cmpgi $r1,$r0,$imm"
|
||||
(+ OP_CMPGI r0 r1 imm)
|
||||
(set r1 (gt SI r0 (ext SI (trunc HI imm))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni cmpge "compare greater or equal" ()
|
||||
"cmpge $r2,$r0,$r1"
|
||||
(+ OP_CMPGE r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (ge SI r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni cmpgei "compare greater or equal immediate" ()
|
||||
"cmpgei $r1,$r0,$imm"
|
||||
(+ OP_CMPGEI r0 r1 imm)
|
||||
(set r1 (ge SI r0 (ext SI (trunc HI imm))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni cmpgeu "compare greater or equal unsigned" ()
|
||||
"cmpgeu $r2,$r0,$r1"
|
||||
(+ OP_CMPGEU r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (geu SI r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni cmpgeui "compare greater or equal unsigned immediate" ()
|
||||
"cmpgeui $r1,$r0,$uimm"
|
||||
(+ OP_CMPGEUI r0 r1 uimm)
|
||||
(set r1 (geu SI r0 (zext SI uimm)))
|
||||
()
|
||||
)
|
||||
|
||||
(dni cmpgu "compare greater than unsigned" ()
|
||||
"cmpgu $r2,$r0,$r1"
|
||||
(+ OP_CMPGU r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (gtu SI r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni cmpgui "compare greater than unsigned immediate" ()
|
||||
"cmpgui $r1,$r0,$uimm"
|
||||
(+ OP_CMPGUI r0 r1 uimm)
|
||||
(set r1 (gtu SI r0 (zext SI uimm)))
|
||||
()
|
||||
)
|
||||
|
||||
(dni cmpne "compare not equal" ()
|
||||
"cmpne $r2,$r0,$r1"
|
||||
(+ OP_CMPNE r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (ne SI r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni cmpnei "compare not equal immediate" ()
|
||||
"cmpnei $r1,$r0,$imm"
|
||||
(+ OP_CMPNEI r0 r1 imm)
|
||||
(set r1 (ne SI r0 (ext SI (trunc HI imm))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni divu "unsigned divide" ()
|
||||
"divu $r2,$r0,$r1"
|
||||
(+ OP_DIVU r0 r1 r2 (f-resv0 0))
|
||||
(set pc (c-call USI "@cpu@_divu_insn" pc f-r0 f-r1 f-r2))
|
||||
()
|
||||
)
|
||||
|
||||
(dni lb "load byte" ()
|
||||
"lb $r1,($r0+$imm)"
|
||||
(+ OP_LB r0 r1 imm)
|
||||
(set r1 (ext SI (mem QI (add r0 (ext SI (trunc HI imm))))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni lbu "load byte unsigned" ()
|
||||
"lbu $r1,($r0+$imm)"
|
||||
(+ OP_LBU r0 r1 imm)
|
||||
(set r1 (zext SI (mem QI (add r0 (ext SI (trunc HI imm))))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni lh "load halfword" ()
|
||||
"lh $r1,($r0+$imm)"
|
||||
(+ OP_LH r0 r1 imm)
|
||||
(set r1 (ext SI (mem HI (add r0 (ext SI (trunc HI imm))))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni lhu "load halfword unsigned" ()
|
||||
"lhu $r1,($r0+$imm)"
|
||||
(+ OP_LHU r0 r1 imm)
|
||||
(set r1 (zext SI (mem HI (add r0 (ext SI (trunc HI imm))))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni lw "load word" ()
|
||||
"lw $r1,($r0+$imm)"
|
||||
(+ OP_LW r0 r1 imm)
|
||||
(set r1 (mem SI (add r0 (ext SI (trunc HI imm)))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni modu "unsigned modulus" ()
|
||||
"modu $r2,$r0,$r1"
|
||||
(+ OP_MODU r0 r1 r2 (f-resv0 0))
|
||||
(set pc (c-call USI "@cpu@_modu_insn" pc f-r0 f-r1 f-r2))
|
||||
()
|
||||
)
|
||||
|
||||
(dni mul "mulitply" ()
|
||||
"mul $r2,$r0,$r1"
|
||||
(+ OP_MUL r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (mul r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni muli "multiply immediate" ()
|
||||
"muli $r1,$r0,$imm"
|
||||
(+ OP_MULI r0 r1 imm)
|
||||
(set r1 (mul r0 (ext SI (trunc HI imm))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni nor "nor" ()
|
||||
"nor $r2,$r0,$r1"
|
||||
(+ OP_NOR r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (inv (or r0 r1)))
|
||||
()
|
||||
)
|
||||
|
||||
(dni nori "nor immediate" ()
|
||||
"nori $r1,$r0,$uimm"
|
||||
(+ OP_NORI r0 r1 uimm)
|
||||
(set r1 (inv (or r0 (zext SI uimm))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni or "or" ()
|
||||
"or $r2,$r0,$r1"
|
||||
(+ OP_OR r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (or r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni ori "or immediate" ()
|
||||
"ori $r1,$r0,$lo16"
|
||||
(+ OP_ORI r0 r1 lo16)
|
||||
(set r1 (or r0 (zext SI lo16)))
|
||||
()
|
||||
)
|
||||
|
||||
(dni orhii "or high immediate" ()
|
||||
"orhi $r1,$r0,$hi16"
|
||||
(+ OP_ORHI r0 r1 hi16)
|
||||
(set r1 (or r0 (sll SI hi16 16)))
|
||||
()
|
||||
)
|
||||
|
||||
(dni rcsr "read control or status register" ()
|
||||
"rcsr $r2,$csr"
|
||||
(+ OP_RCSR csr (f-r1 0) r2 (f-resv0 0))
|
||||
(set r2 csr)
|
||||
()
|
||||
)
|
||||
|
||||
(dni sb "store byte" ()
|
||||
"sb ($r0+$imm),$r1"
|
||||
(+ OP_SB r0 r1 imm)
|
||||
(set (mem QI (add r0 (ext SI (trunc HI imm)))) r1)
|
||||
()
|
||||
)
|
||||
|
||||
(dni sextb "sign extend byte" ()
|
||||
"sextb $r2,$r0"
|
||||
(+ OP_SEXTB r0 (f-r1 0) r2 (f-resv0 0))
|
||||
(set r2 (ext SI (trunc QI r0)))
|
||||
()
|
||||
)
|
||||
|
||||
(dni sexth "sign extend half-word" ()
|
||||
"sexth $r2,$r0"
|
||||
(+ OP_SEXTH r0 (f-r1 0) r2 (f-resv0 0))
|
||||
(set r2 (ext SI (trunc HI r0)))
|
||||
()
|
||||
)
|
||||
|
||||
(dni sh "store halfword" ()
|
||||
"sh ($r0+$imm),$r1"
|
||||
(+ OP_SH r0 r1 imm)
|
||||
(set (mem HI (add r0 (ext SI (trunc HI imm)))) r1)
|
||||
()
|
||||
)
|
||||
|
||||
(dni sl "shift left" ()
|
||||
"sl $r2,$r0,$r1"
|
||||
(+ OP_SL r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (sll SI r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni sli "shift left immediate" ()
|
||||
"sli $r1,$r0,$imm"
|
||||
(+ OP_SLI r0 r1 imm)
|
||||
(set r1 (sll SI r0 imm))
|
||||
()
|
||||
)
|
||||
|
||||
(dni sr "shift right" ()
|
||||
"sr $r2,$r0,$r1"
|
||||
(+ OP_SR r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (sra SI r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni sri "shift right immediate" ()
|
||||
"sri $r1,$r0,$imm"
|
||||
(+ OP_SRI r0 r1 imm)
|
||||
(set r1 (sra SI r0 imm))
|
||||
()
|
||||
)
|
||||
|
||||
(dni sru "shift right unsigned" ()
|
||||
"sru $r2,$r0,$r1"
|
||||
(+ OP_SRU r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (srl SI r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni srui "shift right unsigned immediate" ()
|
||||
"srui $r1,$r0,$imm"
|
||||
(+ OP_SRUI r0 r1 imm)
|
||||
(set r1 (srl SI r0 imm))
|
||||
()
|
||||
)
|
||||
|
||||
(dni sub "subtract" ()
|
||||
"sub $r2,$r0,$r1"
|
||||
(+ OP_SUB r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (sub r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni sw "store word" ()
|
||||
"sw ($r0+$imm),$r1"
|
||||
(+ OP_SW r0 r1 imm)
|
||||
(set (mem SI (add r0 (ext SI (trunc HI imm)))) r1)
|
||||
()
|
||||
)
|
||||
|
||||
(dni user "user defined instruction" ()
|
||||
"user $r2,$r0,$r1,$user"
|
||||
(+ OP_USER r0 r1 r2 user)
|
||||
(set r2 (c-call SI "@cpu@_user_insn" r0 r1 user))
|
||||
()
|
||||
)
|
||||
|
||||
(dni wcsr "write control or status register" ()
|
||||
"wcsr $csr,$r1"
|
||||
(+ OP_WCSR csr r1 (f-r2 0) (f-resv0 0))
|
||||
(c-call VOID "@cpu@_wcsr_insn" f-csr r1)
|
||||
()
|
||||
)
|
||||
|
||||
(dni xor "xor" ()
|
||||
"xor $r2,$r0,$r1"
|
||||
(+ OP_XOR r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (xor r0 r1))
|
||||
()
|
||||
)
|
||||
|
||||
(dni xori "xor immediate" ()
|
||||
"xori $r1,$r0,$uimm"
|
||||
(+ OP_XORI r0 r1 uimm)
|
||||
(set r1 (xor r0 (zext SI uimm)))
|
||||
()
|
||||
)
|
||||
|
||||
(dni xnor "xnor" ()
|
||||
"xnor $r2,$r0,$r1"
|
||||
(+ OP_XNOR r0 r1 r2 (f-resv0 0))
|
||||
(set r2 (inv (xor r0 r1)))
|
||||
()
|
||||
)
|
||||
|
||||
(dni xnori "xnor immediate" ()
|
||||
"xnori $r1,$r0,$uimm"
|
||||
(+ OP_XNORI r0 r1 uimm)
|
||||
(set r1 (inv (xor r0 (zext SI uimm))))
|
||||
()
|
||||
)
|
||||
|
||||
; Pseudo instructions
|
||||
|
||||
(dni break "breakpoint" ()
|
||||
"break"
|
||||
(+ OP_RAISE (f-exception 2))
|
||||
(set pc (c-call USI "@cpu@_break_insn" pc))
|
||||
()
|
||||
)
|
||||
|
||||
(dni scall "system call" ()
|
||||
"scall"
|
||||
(+ OP_RAISE (f-exception 7))
|
||||
(set pc (c-call USI "@cpu@_scall_insn" pc))
|
||||
()
|
||||
)
|
||||
|
||||
(dni bret "return from breakpoint" (ALIAS)
|
||||
"bret"
|
||||
(+ OP_B (f-r0 31) (f-r1 0) (f-r2 0) (f-resv0 0))
|
||||
(set pc (c-call USI "@cpu@_bret_insn" r0))
|
||||
()
|
||||
)
|
||||
|
||||
(dni eret "return from exception" (ALIAS)
|
||||
"eret"
|
||||
(+ OP_B (f-r0 30) (f-r1 0) (f-r2 0) (f-resv0 0))
|
||||
(set pc (c-call USI "@cpu@_eret_insn" r0))
|
||||
()
|
||||
)
|
||||
|
||||
(dni ret "return" (ALIAS)
|
||||
"ret"
|
||||
(+ OP_B (f-r0 29) (f-r1 0) (f-r2 0) (f-resv0 0))
|
||||
(set pc r0)
|
||||
()
|
||||
)
|
||||
|
||||
(dni mv "move" (ALIAS)
|
||||
"mv $r2,$r0"
|
||||
(+ OP_OR r0 (f-r1 0) r2 (f-resv0 0))
|
||||
(set r2 r0)
|
||||
()
|
||||
)
|
||||
|
||||
(dni mvi "move immediate" (ALIAS)
|
||||
"mvi $r1,$imm"
|
||||
(+ OP_ADDI (f-r0 0) r1 imm)
|
||||
(set r1 (add r0 (ext SI (trunc HI imm))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni mvui "move unsigned immediate" (ALIAS)
|
||||
"mvu $r1,$lo16"
|
||||
(+ OP_ORI (f-r0 0) r1 lo16)
|
||||
(set r1 (zext SI lo16))
|
||||
()
|
||||
)
|
||||
|
||||
(dni mvhi "move high immediate" (ALIAS)
|
||||
"mvhi $r1,$hi16"
|
||||
(+ OP_ORHI (f-r0 0) r1 hi16)
|
||||
(set r1 (or r0 (sll SI hi16 16)))
|
||||
()
|
||||
)
|
||||
|
||||
(dni mva "move address" (ALIAS)
|
||||
"mva $r1,$gp16"
|
||||
(+ OP_ADDI (f-r0 26) r1 gp16)
|
||||
(set r1 (add r0 (ext SI (trunc HI gp16))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni not "not" (ALIAS)
|
||||
"not $r2,$r0"
|
||||
(+ OP_XNOR r0 (f-r1 0) r2 (f-resv0 0))
|
||||
(set r2 (inv r0))
|
||||
()
|
||||
)
|
||||
|
||||
(dni nop "nop" (ALIAS)
|
||||
"nop"
|
||||
(+ OP_ADDI (f-r0 0) (f-r1 0) (f-imm 0))
|
||||
(set r0 r0)
|
||||
()
|
||||
)
|
||||
|
||||
(dni lbgprel "load byte gp relative" (ALIAS)
|
||||
"lb $r1,$gp16"
|
||||
(+ OP_LB (f-r0 26) r1 gp16)
|
||||
(set r1 (ext SI (mem QI (add r0 (ext SI (trunc HI gp16))))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni lbugprel "load byte unsigned gp relative" (ALIAS)
|
||||
"lbu $r1,$gp16"
|
||||
(+ OP_LBU (f-r0 26) r1 gp16)
|
||||
(set r1 (zext SI (mem QI (add r0 (ext SI (trunc HI gp16))))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni lhgprel "load halfword gp relative" (ALIAS)
|
||||
"lh $r1,$gp16"
|
||||
(+ OP_LH (f-r0 26) r1 gp16)
|
||||
(set r1 (ext SI (mem HI (add r0 (ext SI (trunc HI gp16))))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni lhugprel "load halfword unsigned gp relative" (ALIAS)
|
||||
"lhu $r1,$gp16"
|
||||
(+ OP_LHU (f-r0 26) r1 gp16)
|
||||
(set r1 (zext SI (mem HI (add r0 (ext SI (trunc HI gp16))))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni lwgprel "load word gp relative" (ALIAS)
|
||||
"lw $r1,$gp16"
|
||||
(+ OP_LW (f-r0 26) r1 gp16)
|
||||
(set r1 (mem SI (add r0 (ext SI (trunc HI gp16)))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni sbgprel "store byte gp relative" (ALIAS)
|
||||
"sb $gp16,$r1"
|
||||
(+ OP_SB (f-r0 26) r1 gp16)
|
||||
(set (mem QI (add r0 (ext SI (trunc HI gp16)))) r1)
|
||||
()
|
||||
)
|
||||
|
||||
(dni shgprel "store halfword gp relative" (ALIAS)
|
||||
"sh $gp16,$r1"
|
||||
(+ OP_SH (f-r0 26) r1 gp16)
|
||||
(set (mem HI (add r0 (ext SI (trunc HI gp16)))) r1)
|
||||
()
|
||||
)
|
||||
|
||||
(dni swgprel "store word gp relative" (ALIAS)
|
||||
"sw $gp16,$r1"
|
||||
(+ OP_SW (f-r0 26) r1 gp16)
|
||||
(set (mem SI (add r0 (ext SI (trunc HI gp16)))) r1)
|
||||
()
|
||||
)
|
||||
|
||||
(dni lwgotrel "load word got relative" (ALIAS)
|
||||
"lw $r1,(gp+$got16)"
|
||||
(+ OP_LW (f-r0 26) r1 got16)
|
||||
(set r1 (mem SI (add r0 (ext SI (trunc HI got16)))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni orhigotoffi "or high got offset immediate" (ALIAS)
|
||||
"orhi $r1,$r0,$gotoffhi16"
|
||||
(+ OP_ORHI r0 r1 gotoffhi16)
|
||||
(set r1 (or r0 (sll SI gotoffhi16 16)))
|
||||
()
|
||||
)
|
||||
|
||||
(dni addgotoff "add got offset" (ALIAS)
|
||||
"addi $r1,$r0,$gotofflo16"
|
||||
(+ OP_ADDI r0 r1 gotofflo16)
|
||||
(set r1 (add r0 (ext SI (trunc HI gotofflo16))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni swgotoff "store word got offset" (ALIAS)
|
||||
"sw ($r0+$gotofflo16),$r1"
|
||||
(+ OP_SW r0 r1 gotofflo16)
|
||||
(set (mem SI (add r0 (ext SI (trunc HI gotofflo16)))) r1)
|
||||
()
|
||||
)
|
||||
|
||||
(dni lwgotoff "load word got offset" (ALIAS)
|
||||
"lw $r1,($r0+$gotofflo16)"
|
||||
(+ OP_LW r0 r1 gotofflo16)
|
||||
(set r1 (mem SI (add r0 (ext SI (trunc HI gotofflo16)))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni shgotoff "store half word got offset" (ALIAS)
|
||||
"sh ($r0+$gotofflo16),$r1"
|
||||
(+ OP_SH r0 r1 gotofflo16)
|
||||
(set (mem HI (add r0 (ext SI (trunc HI gotofflo16)))) r1)
|
||||
()
|
||||
)
|
||||
|
||||
(dni lhgotoff "load half word got offset" (ALIAS)
|
||||
"lh $r1,($r0+$gotofflo16)"
|
||||
(+ OP_LH r0 r1 gotofflo16)
|
||||
(set r1 (ext SI (mem HI (add r0 (ext SI (trunc HI gotofflo16))))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni lhugotoff "load half word got offset unsigned" (ALIAS)
|
||||
"lhu $r1,($r0+$gotofflo16)"
|
||||
(+ OP_LHU r0 r1 gotofflo16)
|
||||
(set r1 (zext SI (mem HI (add r0 (ext SI (trunc HI gotofflo16))))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni sbgotoff "store byte got offset" (ALIAS)
|
||||
"sb ($r0+$gotofflo16),$r1"
|
||||
(+ OP_SB r0 r1 gotofflo16)
|
||||
(set (mem QI (add r0 (ext SI (trunc HI gotofflo16)))) r1)
|
||||
()
|
||||
)
|
||||
|
||||
(dni lbgotoff "load byte got offset" (ALIAS)
|
||||
"lb $r1,($r0+$gotofflo16)"
|
||||
(+ OP_LB r0 r1 gotofflo16)
|
||||
(set r1 (ext SI (mem QI (add r0 (ext SI (trunc HI gotofflo16))))))
|
||||
()
|
||||
)
|
||||
|
||||
(dni lbugotoff "load byte got offset unsigned" (ALIAS)
|
||||
"lbu $r1,($r0+$gotofflo16)"
|
||||
(+ OP_LBU r0 r1 gotofflo16)
|
||||
(set r1 (zext SI (mem QI (add r0 (ext SI (trunc HI gotofflo16))))))
|
||||
()
|
||||
)
|
235
cpu/lm32.opc
Normal file
235
cpu/lm32.opc
Normal file
@ -0,0 +1,235 @@
|
||||
/* Lattice Mico32 opcode support. -*- C -*-
|
||||
Copyright 2008 Free Software Foundation, Inc.
|
||||
Contributed by Jon Beniston <jon@beniston.com>
|
||||
|
||||
This file is part of the GNU Binutils.
|
||||
|
||||
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 3 of the License, 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., 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
/* -- opc.h */
|
||||
|
||||
/* Allows reason codes to be output when assembler errors occur. */
|
||||
#define CGEN_VERBOSE_ASSEMBLER_ERRORS
|
||||
|
||||
#define CGEN_DIS_HASH_SIZE 64
|
||||
#define CGEN_DIS_HASH(buf,value) ((value >> 26) & 0x3f)
|
||||
|
||||
/* -- asm.c */
|
||||
|
||||
/* Handle signed/unsigned literal. */
|
||||
|
||||
static const char *
|
||||
parse_imm (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
unsigned long *valuep)
|
||||
{
|
||||
const char *errmsg;
|
||||
signed long value;
|
||||
|
||||
errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
|
||||
if (errmsg == NULL)
|
||||
{
|
||||
unsigned long x = value & 0xFFFF0000;
|
||||
if (x != 0 && x != 0xFFFF0000)
|
||||
errmsg = _("immediate value out of range");
|
||||
else
|
||||
*valuep = (value & 0xFFFF);
|
||||
}
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
/* Handle hi() */
|
||||
|
||||
static const char *
|
||||
parse_hi16 (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
unsigned long *valuep)
|
||||
{
|
||||
if (strncasecmp (*strp, "hi(", 3) == 0)
|
||||
{
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
const char *errmsg;
|
||||
|
||||
*strp += 3;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return _("missing `)'");
|
||||
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value = (value >> 16) & 0xffff;
|
||||
*valuep = value;
|
||||
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return parse_imm (cd, strp, opindex, valuep);
|
||||
}
|
||||
|
||||
/* Handle lo() */
|
||||
|
||||
static const char *
|
||||
parse_lo16 (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
unsigned long *valuep)
|
||||
{
|
||||
if (strncasecmp (*strp, "lo(", 3) == 0)
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
*strp += 3;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return _("missing `)'");
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value &= 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return parse_imm (cd, strp, opindex, valuep);
|
||||
}
|
||||
|
||||
/* Handle gp() */
|
||||
|
||||
static const char *
|
||||
parse_gp16 (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
long *valuep)
|
||||
{
|
||||
if (strncasecmp (*strp, "gp(", 3) == 0)
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
*strp += 3;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_GPREL16,
|
||||
& result_type, & value);
|
||||
if (**strp != ')')
|
||||
return _("missing `)'");
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value &= 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return _("expecting gp relative address: gp(symbol)");
|
||||
}
|
||||
|
||||
/* Handle got() */
|
||||
|
||||
static const char *
|
||||
parse_got16 (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
long *valuep)
|
||||
{
|
||||
if (strncasecmp (*strp, "got(", 4) == 0)
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
*strp += 4;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_16_GOT,
|
||||
& result_type, & value);
|
||||
if (**strp != ')')
|
||||
return _("missing `)'");
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value &= 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return _("expecting got relative address: got(symbol)");
|
||||
}
|
||||
|
||||
/* Handle gotoffhi16() */
|
||||
|
||||
static const char *
|
||||
parse_gotoff_hi16 (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
long *valuep)
|
||||
{
|
||||
if (strncasecmp (*strp, "gotoffhi16(", 11) == 0)
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
*strp += 11;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_HI16,
|
||||
& result_type, & value);
|
||||
if (**strp != ')')
|
||||
return _("missing `)'");
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value &= 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return _("expecting got relative address: gotoffhi16(symbol)");
|
||||
}
|
||||
|
||||
/* Handle gotofflo16() */
|
||||
|
||||
static const char *
|
||||
parse_gotoff_lo16 (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
long *valuep)
|
||||
{
|
||||
if (strncasecmp (*strp, "gotofflo16(", 11) == 0)
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
*strp += 11;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_LO16,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return _("missing `)'");
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value &= 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return _("expecting got relative address: gotofflo16(symbol)");
|
||||
}
|
@ -1,3 +1,19 @@
|
||||
2008-12-23 Jon Beniston <jon@beniston.com>
|
||||
|
||||
* NEWS: Record that support for LM32 has been added.
|
||||
* Makefile.am: Add LM32 object files and dependencies.
|
||||
* Makefile.in: Regenerate.
|
||||
* configure.in: Indicate LM32 uses cgen.
|
||||
* configure: Regenerate.
|
||||
* configure.tgt: Add LM32 target.
|
||||
* config/tc-lm32.c: New file.
|
||||
* config/tc-lm32.h: New file.
|
||||
* doc/Makefile.am: Add c-lm32.texi to CPU_DOCS.
|
||||
* doc/Makefile.in: Regenerate.
|
||||
* doc/all.texi: Add LM32 as CPU of interest.
|
||||
* doc/as.texinfo: Add LM32 dependent features link.
|
||||
* doc/c-lm32.texi: New file.
|
||||
|
||||
2008-12-23 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* config/tc-i386.c (match_template): Changed to return
|
||||
|
@ -64,6 +64,7 @@ CPU_TYPES = \
|
||||
i960 \
|
||||
ia64 \
|
||||
ip2k \
|
||||
lm32 \
|
||||
m32c \
|
||||
m32r \
|
||||
m68hc11 \
|
||||
@ -259,6 +260,7 @@ TARGET_CPU_CFILES = \
|
||||
config/tc-i960.c \
|
||||
config/tc-ip2k.c \
|
||||
config/tc-iq2000.c \
|
||||
config/tc-lm32.c \
|
||||
config/tc-m32c.c \
|
||||
config/tc-m32r.c \
|
||||
config/tc-m68hc11.c \
|
||||
@ -319,6 +321,7 @@ TARGET_CPU_HFILES = \
|
||||
config/tc-i960.h \
|
||||
config/tc-ip2k.h \
|
||||
config/tc-iq2000.h \
|
||||
config/tc-lm32.h \
|
||||
config/tc-m32c.h \
|
||||
config/tc-m32r.h \
|
||||
config/tc-m68hc11.h \
|
||||
@ -1195,6 +1198,13 @@ DEPTC_ip2k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/opcode/cgen-bitset.h $(srcdir)/../opcodes/ip2k-opc.h \
|
||||
cgen.h $(INCDIR)/elf/ip2k.h $(INCDIR)/elf/reloc-macros.h \
|
||||
$(BFDDIR)/libbfd.h $(INCDIR)/hashtab.h
|
||||
DEPTC_lm32_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-lm32.h \
|
||||
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
|
||||
$(srcdir)/../opcodes/lm32-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
$(srcdir)/../opcodes/lm32-opc.h cgen.h $(INCDIR)/elf/lm32.h \
|
||||
$(INCDIR)/elf/reloc-macros.h
|
||||
DEPTC_m32c_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32c.h dwarf2dbg.h \
|
||||
@ -1610,6 +1620,11 @@ DEPOBJ_ip2k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h dwarf2dbg.h \
|
||||
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
|
||||
struc-symbol.h $(INCDIR)/aout/aout64.h
|
||||
DEPOBJ_lm32_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-lm32.h \
|
||||
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
|
||||
struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
|
||||
DEPOBJ_m32c_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32c.h dwarf2dbg.h \
|
||||
@ -1953,6 +1968,9 @@ DEP_ip2k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h dwarf2dbg.h \
|
||||
$(srcdir)/config/obj-coff.h $(INCDIR)/coff/internal.h \
|
||||
$(BFDDIR)/libcoff.h
|
||||
DEP_lm32_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-lm32.h
|
||||
DEP_m32c_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32c.h dwarf2dbg.h \
|
||||
|
@ -326,6 +326,7 @@ CPU_TYPES = \
|
||||
i960 \
|
||||
ia64 \
|
||||
ip2k \
|
||||
lm32 \
|
||||
m32c \
|
||||
m32r \
|
||||
m68hc11 \
|
||||
@ -519,6 +520,7 @@ TARGET_CPU_CFILES = \
|
||||
config/tc-i960.c \
|
||||
config/tc-ip2k.c \
|
||||
config/tc-iq2000.c \
|
||||
config/tc-lm32.c \
|
||||
config/tc-m32c.c \
|
||||
config/tc-m32r.c \
|
||||
config/tc-m68hc11.c \
|
||||
@ -579,6 +581,7 @@ TARGET_CPU_HFILES = \
|
||||
config/tc-i960.h \
|
||||
config/tc-ip2k.h \
|
||||
config/tc-iq2000.h \
|
||||
config/tc-lm32.h \
|
||||
config/tc-m32c.h \
|
||||
config/tc-m32r.h \
|
||||
config/tc-m68hc11.h \
|
||||
@ -998,6 +1001,14 @@ DEPTC_ip2k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
|
||||
cgen.h $(INCDIR)/elf/ip2k.h $(INCDIR)/elf/reloc-macros.h \
|
||||
$(BFDDIR)/libbfd.h $(INCDIR)/hashtab.h
|
||||
|
||||
DEPTC_lm32_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-lm32.h \
|
||||
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
|
||||
$(srcdir)/../opcodes/lm32-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
$(srcdir)/../opcodes/lm32-opc.h cgen.h $(INCDIR)/elf/lm32.h \
|
||||
$(INCDIR)/elf/reloc-macros.h
|
||||
|
||||
DEPTC_m32c_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32c.h dwarf2dbg.h \
|
||||
@ -1493,6 +1504,12 @@ DEPOBJ_ip2k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
|
||||
struc-symbol.h $(INCDIR)/aout/aout64.h
|
||||
|
||||
DEPOBJ_lm32_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-lm32.h \
|
||||
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
|
||||
struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
|
||||
|
||||
DEPOBJ_m32c_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32c.h dwarf2dbg.h \
|
||||
@ -1916,6 +1933,10 @@ DEP_ip2k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
|
||||
$(srcdir)/config/obj-coff.h $(INCDIR)/coff/internal.h \
|
||||
$(BFDDIR)/libcoff.h
|
||||
|
||||
DEP_lm32_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-lm32.h
|
||||
|
||||
DEP_m32c_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32c.h dwarf2dbg.h \
|
||||
|
2
gas/NEWS
2
gas/NEWS
@ -1,5 +1,7 @@
|
||||
-*- text -*-
|
||||
|
||||
* Add support for Lattice Mico32 (lm32) architecture.
|
||||
|
||||
Changes in 2.19:
|
||||
|
||||
* New pseudo op .cfi_val_encoded_addr, to record constant addresses in unwind
|
||||
|
419
gas/config/tc-lm32.c
Normal file
419
gas/config/tc-lm32.c
Normal file
@ -0,0 +1,419 @@
|
||||
/* tc-lm32.c - Lattice Mico32 assembler.
|
||||
Copyright 2008 Free Software Foundation, Inc.
|
||||
Contributed by Jon Beniston <jon@beniston.com>
|
||||
|
||||
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, 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "as.h"
|
||||
#include "safe-ctype.h"
|
||||
#include "subsegs.h"
|
||||
#include "bfd.h"
|
||||
#include "safe-ctype.h"
|
||||
#include "opcodes/lm32-desc.h"
|
||||
#include "opcodes/lm32-opc.h"
|
||||
#include "cgen.h"
|
||||
#include "elf/lm32.h"
|
||||
|
||||
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];
|
||||
} lm32_insn;
|
||||
|
||||
/* Configuration options */
|
||||
|
||||
#define LM_CFG_MULTIPLIY_ENABLED 0x0001
|
||||
#define LM_CFG_DIVIDE_ENABLED 0x0002
|
||||
#define LM_CFG_BARREL_SHIFT_ENABLED 0x0004
|
||||
#define LM_CFG_SIGN_EXTEND_ENABLED 0x0008
|
||||
#define LM_CFG_USER_ENABLED 0x0010
|
||||
#define LM_CFG_ICACHE_ENABLED 0x0020
|
||||
#define LM_CFG_DCACHE_ENABLED 0x0040
|
||||
#define LM_CFG_BREAK_ENABLED 0x0080
|
||||
|
||||
static unsigned config = 0U;
|
||||
|
||||
/* Target specific assembler tokens / delimiters. */
|
||||
|
||||
const char comment_chars[] = "#";
|
||||
const char line_comment_chars[] = "#";
|
||||
const char line_separator_chars[] = ";";
|
||||
const char EXP_CHARS[] = "eE";
|
||||
const char FLT_CHARS[] = "dD";
|
||||
|
||||
/* Target specific assembly directives. */
|
||||
|
||||
const pseudo_typeS md_pseudo_table[] =
|
||||
{
|
||||
{ "align", s_align_bytes, 0 },
|
||||
{ "byte", cons, 1 },
|
||||
{ "hword", cons, 2 },
|
||||
{ "word", cons, 4 },
|
||||
{ "dword", cons, 8 },
|
||||
{(char *)0 , (void(*)(int))0, 0}
|
||||
};
|
||||
|
||||
/* Target specific command line options. */
|
||||
|
||||
const char * md_shortopts = "";
|
||||
|
||||
struct option md_longopts[] =
|
||||
{
|
||||
#define OPTION_MULTIPLY_ENABLED (OPTION_MD_BASE + 1)
|
||||
{ "mmultiply-enabled", no_argument, NULL, OPTION_MULTIPLY_ENABLED },
|
||||
#define OPTION_DIVIDE_ENABLED (OPTION_MD_BASE + 2)
|
||||
{ "mdivide-enabled", no_argument, NULL, OPTION_DIVIDE_ENABLED },
|
||||
#define OPTION_BARREL_SHIFT_ENABLED (OPTION_MD_BASE + 3)
|
||||
{ "mbarrel-shift-enabled", no_argument, NULL, OPTION_BARREL_SHIFT_ENABLED },
|
||||
#define OPTION_SIGN_EXTEND_ENABLED (OPTION_MD_BASE + 4)
|
||||
{ "msign-extend-enabled", no_argument, NULL, OPTION_SIGN_EXTEND_ENABLED },
|
||||
#define OPTION_USER_ENABLED (OPTION_MD_BASE + 5)
|
||||
{ "muser-enabled", no_argument, NULL, OPTION_USER_ENABLED },
|
||||
#define OPTION_ICACHE_ENABLED (OPTION_MD_BASE + 6)
|
||||
{ "micache-enabled", no_argument, NULL, OPTION_ICACHE_ENABLED },
|
||||
#define OPTION_DCACHE_ENABLED (OPTION_MD_BASE + 7)
|
||||
{ "mdcache-enabled", no_argument, NULL, OPTION_DCACHE_ENABLED },
|
||||
#define OPTION_BREAK_ENABLED (OPTION_MD_BASE + 8)
|
||||
{ "mbreak-enabled", no_argument, NULL, OPTION_BREAK_ENABLED },
|
||||
#define OPTION_ALL_ENABLED (OPTION_MD_BASE + 9)
|
||||
{ "mall-enabled", no_argument, NULL, OPTION_ALL_ENABLED },
|
||||
};
|
||||
|
||||
size_t md_longopts_size = sizeof (md_longopts);
|
||||
|
||||
/* Display architecture specific options. */
|
||||
|
||||
void
|
||||
md_show_usage (FILE * fp)
|
||||
{
|
||||
fprintf (fp, "LM32 specific options:\n"
|
||||
" -mmultiply-enabled enable multiply instructions\n"
|
||||
" -mdivide-enabled enable divide and modulus instructions\n"
|
||||
" -mbarrel-shift-enabled enable multi-bit shift instructions\n"
|
||||
" -msign-extend-enabled enable sign-extension instructions\n"
|
||||
" -muser-enabled enable user-defined instructions\n"
|
||||
" -micache-enabled enable instruction cache instructions\n"
|
||||
" -mdcache-enabled enable data cache instructions\n"
|
||||
" -mbreak-enabled enable the break instruction\n"
|
||||
" -mall-enabled enable all optional instructions\n"
|
||||
);
|
||||
}
|
||||
|
||||
/* Parse command line options. */
|
||||
|
||||
int
|
||||
md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case OPTION_MULTIPLY_ENABLED:
|
||||
config |= LM_CFG_MULTIPLIY_ENABLED;
|
||||
break;
|
||||
case OPTION_DIVIDE_ENABLED:
|
||||
config |= LM_CFG_DIVIDE_ENABLED;
|
||||
break;
|
||||
case OPTION_BARREL_SHIFT_ENABLED:
|
||||
config |= LM_CFG_BARREL_SHIFT_ENABLED;
|
||||
break;
|
||||
case OPTION_SIGN_EXTEND_ENABLED:
|
||||
config |= LM_CFG_SIGN_EXTEND_ENABLED;
|
||||
break;
|
||||
case OPTION_USER_ENABLED:
|
||||
config |= LM_CFG_USER_ENABLED;
|
||||
break;
|
||||
case OPTION_ICACHE_ENABLED:
|
||||
config |= LM_CFG_ICACHE_ENABLED;
|
||||
break;
|
||||
case OPTION_DCACHE_ENABLED:
|
||||
config |= LM_CFG_DCACHE_ENABLED;
|
||||
break;
|
||||
case OPTION_BREAK_ENABLED:
|
||||
config |= LM_CFG_BREAK_ENABLED;
|
||||
break;
|
||||
case OPTION_ALL_ENABLED:
|
||||
config |= LM_CFG_MULTIPLIY_ENABLED;
|
||||
config |= LM_CFG_DIVIDE_ENABLED;
|
||||
config |= LM_CFG_BARREL_SHIFT_ENABLED;
|
||||
config |= LM_CFG_SIGN_EXTEND_ENABLED;
|
||||
config |= LM_CFG_USER_ENABLED;
|
||||
config |= LM_CFG_ICACHE_ENABLED;
|
||||
config |= LM_CFG_DCACHE_ENABLED;
|
||||
config |= LM_CFG_BREAK_ENABLED;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Do any architecture specific initialisation. */
|
||||
|
||||
void
|
||||
md_begin (void)
|
||||
{
|
||||
/* Initialize the `cgen' interface. */
|
||||
|
||||
/* Set the machine number and endian. */
|
||||
gas_cgen_cpu_desc = lm32_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
|
||||
CGEN_CPU_OPEN_ENDIAN,
|
||||
CGEN_ENDIAN_BIG,
|
||||
CGEN_CPU_OPEN_END);
|
||||
lm32_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);
|
||||
}
|
||||
|
||||
/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
|
||||
for use in the a.out file, and stores them in the array pointed to by buf. */
|
||||
|
||||
void
|
||||
md_number_to_chars (char * buf, valueT val, int n)
|
||||
{
|
||||
if (target_big_endian)
|
||||
number_to_chars_bigendian (buf, val, n);
|
||||
else
|
||||
number_to_chars_littleendian (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. */
|
||||
|
||||
char *
|
||||
md_atof (int type, char *litP, int *sizeP)
|
||||
{
|
||||
int i;
|
||||
int prec;
|
||||
LITTLENUM_TYPE words[4];
|
||||
|
||||
char *t;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 'f':
|
||||
prec = 2;
|
||||
break;
|
||||
case 'd':
|
||||
prec = 4;
|
||||
break;
|
||||
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);
|
||||
|
||||
if (target_big_endian)
|
||||
{
|
||||
for (i = 0; i < prec; i++)
|
||||
{
|
||||
md_number_to_chars (litP, (valueT) words[i],
|
||||
sizeof (LITTLENUM_TYPE));
|
||||
litP += sizeof (LITTLENUM_TYPE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = prec - 1; i >= 0; i--)
|
||||
{
|
||||
md_number_to_chars (litP, (valueT) words[i],
|
||||
sizeof (LITTLENUM_TYPE));
|
||||
litP += sizeof (LITTLENUM_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Called for each undefined symbol. */
|
||||
|
||||
symbolS *
|
||||
md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Round up a section size to the appropriate boundary. */
|
||||
|
||||
valueT
|
||||
md_section_align (asection *seg, valueT addr)
|
||||
{
|
||||
int align = bfd_get_section_alignment (stdoutput, seg);
|
||||
return ((addr + (1 << align) - 1) & (-1 << align));
|
||||
}
|
||||
|
||||
/* This function assembles the instructions. It emits the frags/bytes to the
|
||||
sections and creates the relocation entries. */
|
||||
|
||||
void
|
||||
md_assemble (char * str)
|
||||
{
|
||||
lm32_insn insn;
|
||||
char * errmsg;
|
||||
|
||||
/* Initialize GAS's cgen interface for a new instruction. */
|
||||
gas_cgen_init_parse ();
|
||||
|
||||
insn.insn = lm32_cgen_assemble_insn
|
||||
(gas_cgen_cpu_desc, str, &insn.fields, insn.buffer, &errmsg);
|
||||
|
||||
if (!insn.insn)
|
||||
{
|
||||
as_bad ("%s", errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
gas_cgen_finish_insn (insn.insn, insn.buffer,
|
||||
CGEN_FIELDS_BITSIZE (&insn.fields), 1, NULL);
|
||||
}
|
||||
|
||||
/* 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 (const CGEN_INSN *insn ATTRIBUTE_UNUSED,
|
||||
const CGEN_OPERAND *operand,
|
||||
fixS *fixP ATTRIBUTE_UNUSED)
|
||||
{
|
||||
switch (operand->type)
|
||||
{
|
||||
case LM32_OPERAND_GOT16:
|
||||
return BFD_RELOC_LM32_16_GOT;
|
||||
case LM32_OPERAND_GOTOFFHI16:
|
||||
return BFD_RELOC_LM32_GOTOFF_HI16;
|
||||
case LM32_OPERAND_GOTOFFLO16:
|
||||
return BFD_RELOC_LM32_GOTOFF_LO16;
|
||||
case LM32_OPERAND_GP16:
|
||||
return BFD_RELOC_GPREL16;
|
||||
case LM32_OPERAND_LO16:
|
||||
return BFD_RELOC_LO16;
|
||||
case LM32_OPERAND_HI16:
|
||||
return BFD_RELOC_HI16;
|
||||
case LM32_OPERAND_BRANCH:
|
||||
return BFD_RELOC_LM32_BRANCH;
|
||||
case LM32_OPERAND_CALL:
|
||||
return BFD_RELOC_LM32_CALL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return BFD_RELOC_NONE;
|
||||
}
|
||||
|
||||
/* Return the position from which the PC relative adjustment for a PC relative
|
||||
fixup should be made. */
|
||||
|
||||
long
|
||||
md_pcrel_from (fixS *fixP)
|
||||
{
|
||||
/* Shouldn't get called. */
|
||||
abort ();
|
||||
/* Return address of current instruction. */
|
||||
return fixP->fx_where + fixP->fx_frag->fr_address;
|
||||
}
|
||||
|
||||
/* The location from which a PC relative jump should be calculated,
|
||||
given a PC relative reloc. */
|
||||
|
||||
long
|
||||
md_pcrel_from_section (fixS * fixP, segT sec)
|
||||
{
|
||||
if ((fixP->fx_addsy != (symbolS *) NULL)
|
||||
&& (! S_IS_DEFINED (fixP->fx_addsy)
|
||||
|| (S_GET_SEGMENT (fixP->fx_addsy) != sec)))
|
||||
{
|
||||
/* The symbol is undefined (or is defined but not in this section).
|
||||
Let the linker figure it out. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*fprintf(stderr, "%s extern %d local %d\n", S_GET_NAME (fixP->fx_addsy), S_IS_EXTERN (fixP->fx_addsy), S_IS_LOCAL (fixP->fx_addsy));*/
|
||||
/* FIXME: Weak problem? */
|
||||
if ((fixP->fx_addsy != (symbolS *) NULL)
|
||||
&& S_IS_EXTERNAL (fixP->fx_addsy))
|
||||
{
|
||||
/* If the symbol is external, let the linker handle it. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return fixP->fx_where + fixP->fx_frag->fr_address;
|
||||
}
|
||||
|
||||
/* Return true if we can partially resolve a relocation now. */
|
||||
|
||||
bfd_boolean
|
||||
lm32_fix_adjustable (fixS * fixP)
|
||||
{
|
||||
/* We need the symbol name for the VTABLE entries */
|
||||
if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|
||||
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Relaxation isn't required/supported on this target. */
|
||||
|
||||
int
|
||||
md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
|
||||
asection *seg ATTRIBUTE_UNUSED)
|
||||
{
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
asection *sec ATTRIBUTE_UNUSED,
|
||||
fragS *fragP ATTRIBUTE_UNUSED)
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
||||
void
|
||||
md_apply_fix (fixS * fixP, valueT * valP, segT seg)
|
||||
{
|
||||
/* Fix for weak symbols. Why do we have fx_addsy for weak symbols? */
|
||||
if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy))
|
||||
*valP = 0;
|
||||
|
||||
gas_cgen_md_apply_fix (fixP, valP, seg);
|
||||
return;
|
||||
}
|
50
gas/config/tc-lm32.h
Normal file
50
gas/config/tc-lm32.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* tc-lm32.h -- Header file for tc-lm32.c
|
||||
Copyright 2008 Free Software Foundation, Inc.
|
||||
Contributed by Jon Beniston <jon@beniston.com>
|
||||
|
||||
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 3, 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, 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
#ifndef TC_LM32_H
|
||||
#define TC_LM32_H
|
||||
|
||||
#define TARGET_FORMAT "elf32-lm32"
|
||||
#define TARGET_ARCH bfd_arch_lm32
|
||||
#define TARGET_MACH bfd_mach_lm32
|
||||
|
||||
#define TARGET_BYTES_BIG_ENDIAN 1
|
||||
|
||||
/* Permit temporary numeric labels. */
|
||||
#define LOCAL_LABELS_FB 1
|
||||
|
||||
#define WORKING_DOT_WORD
|
||||
|
||||
/* Values passed to md_apply_fix3 don't include the symbol value. */
|
||||
#define MD_APPLY_SYM_VALUE(FIX) 0
|
||||
|
||||
#define md_operand(X)
|
||||
#define tc_gen_reloc gas_cgen_tc_gen_reloc
|
||||
|
||||
/* Call md_pcrel_from_section(), not md_pcrel_from(). */
|
||||
extern long md_pcrel_from_section (struct fix *, segT);
|
||||
#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC)
|
||||
|
||||
extern bfd_boolean lm32_fix_adjustable (struct fix *);
|
||||
#define tc_fix_adjustable(FIX) lm32_fix_adjustable (FIX)
|
||||
|
||||
#endif /* TC_LM32_H */
|
||||
|
2
gas/configure
vendored
2
gas/configure
vendored
@ -12246,7 +12246,7 @@ _ACEOF
|
||||
fi
|
||||
;;
|
||||
|
||||
fr30 | ip2k | iq2000 | m32r | openrisc)
|
||||
fr30 | ip2k | iq2000 | lm32 | m32r | openrisc)
|
||||
using_cgen=yes
|
||||
;;
|
||||
|
||||
|
@ -308,7 +308,7 @@ changequote([,])dnl
|
||||
fi
|
||||
;;
|
||||
|
||||
fr30 | ip2k | iq2000 | m32r | openrisc)
|
||||
fr30 | ip2k | iq2000 | lm32 | m32r | openrisc)
|
||||
using_cgen=yes
|
||||
;;
|
||||
|
||||
|
@ -44,6 +44,7 @@ case ${cpu} in
|
||||
ia64) cpu_type=ia64 ;;
|
||||
ip2k) cpu_type=ip2k endian=big ;;
|
||||
iq2000) cpu_type=iq2000 endian=big ;;
|
||||
lm32) cpu_type=lm32 ;;
|
||||
m32c) cpu_type=m32c endian=big ;;
|
||||
m32r) cpu_type=m32r endian=big ;;
|
||||
m32rle) cpu_type=m32r endian=little ;;
|
||||
@ -246,6 +247,8 @@ case ${generic_target} in
|
||||
|
||||
m32c-*-elf | m32c-*-rtems*) fmt=elf ;;
|
||||
|
||||
lm32-*-*) fmt=elf ;;
|
||||
|
||||
m32r-*-elf* | m32r-*-rtems*) fmt=elf ;;
|
||||
m32r-*-linux*) fmt=elf em=linux;;
|
||||
|
||||
|
@ -44,6 +44,7 @@ CPU_DOCS = \
|
||||
c-i860.texi \
|
||||
c-i960.texi \
|
||||
c-ip2k.texi \
|
||||
c-lm32.texi \
|
||||
c-m32c.texi \
|
||||
c-m32r.texi \
|
||||
c-m68hc11.texi \
|
||||
|
@ -264,6 +264,7 @@ CPU_DOCS = \
|
||||
c-i860.texi \
|
||||
c-i960.texi \
|
||||
c-ip2k.texi \
|
||||
c-lm32.texi \
|
||||
c-m32c.texi \
|
||||
c-m32r.texi \
|
||||
c-m68hc11.texi \
|
||||
|
@ -43,6 +43,7 @@
|
||||
@set I960
|
||||
@set IA64
|
||||
@set IP2K
|
||||
@set LM32
|
||||
@set M32C
|
||||
@set M32R
|
||||
@set xc16x
|
||||
|
@ -6679,6 +6679,9 @@ subject, see the hardware manufacturer's manual.
|
||||
@ifset IP2K
|
||||
* IP2K-Dependent:: IP2K Dependent Features
|
||||
@end ifset
|
||||
@ifset LM32
|
||||
* LM32-Dependent:: LM32 Dependent Features
|
||||
@end ifset
|
||||
@ifset M32C
|
||||
* M32C-Dependent:: M32C Dependent Features
|
||||
@end ifset
|
||||
@ -6833,6 +6836,10 @@ family.
|
||||
@include c-ip2k.texi
|
||||
@end ifset
|
||||
|
||||
@ifset LM32
|
||||
@include c-lm32.texi
|
||||
@end ifset
|
||||
|
||||
@ifset M32C
|
||||
@include c-m32c.texi
|
||||
@end ifset
|
||||
@ -7212,6 +7219,8 @@ Inc.@: added support for Xtensa processors.
|
||||
Several engineers at Cygnus Support have also provided many small bug fixes and
|
||||
configuration enhancements.
|
||||
|
||||
Jon Beniston added support for the Lattice Mico32 architecture.
|
||||
|
||||
Many others have contributed large or small bugfixes and enhancements. If
|
||||
you have contributed significant work and are not mentioned on this list, and
|
||||
want to be, let us know. Some of the history has been lost; we are not
|
||||
|
215
gas/doc/c-lm32.texi
Normal file
215
gas/doc/c-lm32.texi
Normal file
@ -0,0 +1,215 @@
|
||||
@c Copyright 2008
|
||||
@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 LM32-Dependent
|
||||
@chapter LM32 Dependent Features
|
||||
@end ifset
|
||||
|
||||
@ifclear GENERIC
|
||||
@node Machine Dependencies
|
||||
@chapter LM£" Dependent Features
|
||||
@end ifclear
|
||||
|
||||
@cindex LM32 support
|
||||
@menu
|
||||
* LM32 Options:: Options
|
||||
* LM32 Syntax:: Syntax
|
||||
* LM32 Opcodes:: Opcodes
|
||||
@end menu
|
||||
|
||||
@node LM32 Options
|
||||
@section Options
|
||||
@cindex LM32 options (none)
|
||||
@cindex options for LM32 (none)
|
||||
|
||||
@table @code
|
||||
|
||||
@cindex @code{-mmultiply-enabled} command line option, LM32
|
||||
@item -mmultiply-enabled
|
||||
Enable multiply instructions.
|
||||
|
||||
@cindex @code{-mdivide-enabled} command line option, LM32
|
||||
@item -mdivide-enabled
|
||||
Enable divide instructions.
|
||||
|
||||
@cindex @code{-mbarrel-shift-enabled} command line option, LM32
|
||||
@item -mbarrel-shift-enabled
|
||||
Enable barrel-shift instructions.
|
||||
|
||||
@cindex @code{-msign-extend-enabled} command line option, LM32
|
||||
@item -msign-extend-enabled
|
||||
Enable sign extend instructions.
|
||||
|
||||
@cindex @code{-muser-enabled} command line option, LM32
|
||||
@item -muser-enabled
|
||||
Enable user defined instructions.
|
||||
|
||||
@cindex @code{-micache-enabled} command line option, LM32
|
||||
@item -micache-enabled
|
||||
Enable instruction cache related CSRs.
|
||||
|
||||
@cindex @code{-mdcache-enabled} command line option, LM32
|
||||
@item -mdcache-enabled
|
||||
Enable data cache related CSRs.
|
||||
|
||||
@cindex @code{-mbreak-enabled} command line option, LM32
|
||||
@item -mbreak-enabled
|
||||
Enable break instructions.
|
||||
|
||||
@cindex @code{-mall-enabled} command line option, LM32
|
||||
@item -mall-enabled
|
||||
Enable all instructions and CSRs.
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
@node LM32 Syntax
|
||||
@section Syntax
|
||||
@menu
|
||||
* LM32-Regs:: Register Names
|
||||
* LM32-Modifiers:: Relocatable Expression Modifiers
|
||||
@end menu
|
||||
|
||||
@node LM32-Regs
|
||||
@subsection Register Names
|
||||
|
||||
@cindex LM32 register names
|
||||
@cindex register names, LM32
|
||||
|
||||
LM32 has 32 x 32-bit general purpose registers @samp{r0},
|
||||
@samp{r1}, ... @samp{r31}.
|
||||
|
||||
The following aliases are defined: @samp{gp} - @samp{r26},
|
||||
@samp{fp} - @samp{r27}, @samp{sp} - @samp{r28},
|
||||
@samp{ra} - @samp{r29}, @samp{ea} - @samp{r30},
|
||||
@samp{ba} - @samp{r31}.
|
||||
|
||||
LM32 has the following Control and Status Registers (CSRs).
|
||||
|
||||
@table @code
|
||||
@item IE
|
||||
Interrupt enable.
|
||||
@item IM
|
||||
Interrupt mask.
|
||||
@item IP
|
||||
Interrupt pending.
|
||||
@item ICC
|
||||
Instruction cache control.
|
||||
@item DCC
|
||||
Data cache control.
|
||||
@item CC
|
||||
Cycle counter.
|
||||
@item CFG
|
||||
Configuration.
|
||||
@item EBA
|
||||
Exception base address.
|
||||
@item DC
|
||||
Debug control.
|
||||
@item DEBA
|
||||
Debug exception base address.
|
||||
@item JTX
|
||||
JTAG transmit.
|
||||
@item JRX
|
||||
JTAG receive.
|
||||
@item BP0
|
||||
Breakpoint 0.
|
||||
@item BP1
|
||||
Breakpoint 1.
|
||||
@item BP2
|
||||
Breakpoint 2.
|
||||
@item BP3
|
||||
Breakpoint 3.
|
||||
@item WP0
|
||||
Watchpoint 0.
|
||||
@item WP1
|
||||
Watchpoint 1.
|
||||
@item WP2
|
||||
Watchpoint 2.
|
||||
@item WP3
|
||||
Watchpoint 3.
|
||||
@end table
|
||||
|
||||
@node LM32-Modifiers
|
||||
@subsection Relocatable Expression Modifiers
|
||||
|
||||
@cindex LM32 modifiers
|
||||
@cindex syntax, LM32
|
||||
|
||||
The assembler supports several modifiers when using relocatable addresses
|
||||
in LM32 instruction operands. The general syntax is the following:
|
||||
|
||||
@smallexample
|
||||
modifier(relocatable-expression)
|
||||
@end smallexample
|
||||
|
||||
@table @code
|
||||
@cindex symbol modifiers
|
||||
|
||||
@item lo
|
||||
|
||||
This modifier allows you to use bits 0 through 15 of
|
||||
an address expression as 16 bit relocatable expression.
|
||||
|
||||
@item hi
|
||||
|
||||
This modifier allows you to use bits 16 through 23 of an address expression
|
||||
as 16 bit relocatable expression.
|
||||
|
||||
For example
|
||||
|
||||
@smallexample
|
||||
ori r4, r4, lo(sym+10)
|
||||
orhi r4, r4, hi(sym+10)
|
||||
@end smallexample
|
||||
|
||||
@item gp
|
||||
|
||||
This modified creates a 16-bit relocatable expression that is
|
||||
the offset of the symbol from the global pointer.
|
||||
|
||||
@smallexample
|
||||
mva r4, gp(sym)
|
||||
@end smallexample
|
||||
|
||||
@item got
|
||||
|
||||
This modifier places a symbol in the GOT and creates a 16-bit
|
||||
relocatable expression that is the offset into the GOT of this
|
||||
symbol.
|
||||
|
||||
@smallexample
|
||||
lw r4, (gp+got(sym))
|
||||
@end smallexample
|
||||
|
||||
@item gotofflo16
|
||||
|
||||
This modifier allows you to use the bits 0 through 15 of an
|
||||
address which is an offset from the GOT.
|
||||
|
||||
@item gotoffhi16
|
||||
|
||||
This modifier allows you to use the bits 16 through 31 of an
|
||||
address which is an offset from the GOT.
|
||||
|
||||
@smallexample
|
||||
orhi r4, r4, gotoffhi16(lsym)
|
||||
addi r4, r4, gotofflo16(lsym)
|
||||
@end smallexample
|
||||
|
||||
@end table
|
||||
|
||||
@node LM32 Opcodes
|
||||
@section Opcodes
|
||||
|
||||
@cindex LM32 opcode summary
|
||||
@cindex opcode summary, LM32
|
||||
@cindex mnemonics, LM32
|
||||
@cindex instruction summary, LM32
|
||||
For detailed information on the LM32 machine instruction set, see
|
||||
@url{http://www.latticesemi.com/products/intellectualproperty/ipcores/mico32/}.
|
||||
|
||||
@code{@value{AS}} implements all the standard LM32 opcodes.
|
@ -1,3 +1,12 @@
|
||||
2008-12-23 Jon Beniston <jon@beniston.com>
|
||||
|
||||
* gas/lm32: New directory.
|
||||
* gas/lm32/all.exp: New file.
|
||||
* gas/lm32/csr.d: New file.
|
||||
* gas/lm32/csr.s: New file.
|
||||
* gas/lm32/insn.d: New file.
|
||||
* gas/lm32/insn.s: New file.
|
||||
|
||||
2008-12-23 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* gas/i386/i386.exp: Run x86-64-avx-swap and x86-64-avx-swap-intel.
|
||||
|
@ -1,3 +1,7 @@
|
||||
2008-12-23 Jon Beniston <jon@beniston.com>
|
||||
|
||||
* dis-asm.h: Add LM32 disassembler function prototype.
|
||||
|
||||
2008-12-10 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* demangle.h (enum demangle_component_type): Add
|
||||
|
@ -245,6 +245,7 @@ extern int print_insn_little_mips (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_little_or32 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_little_powerpc (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_little_score (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_lm32 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_m32c (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_m32r (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_m68hc11 (bfd_vma, disassemble_info *);
|
||||
|
@ -1,3 +1,7 @@
|
||||
2008-12-23 Jon Beniston <jon@beniston.com>
|
||||
|
||||
* lm32.h: New file.
|
||||
|
||||
2008-12-23 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* commmon.h (STT_IFUNC): Delete.
|
||||
|
56
include/elf/lm32.h
Normal file
56
include/elf/lm32.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* Lattice Mico32 ELF support for BFD.
|
||||
Copyright 2008 Free Software Foundation, Inc.
|
||||
Contributed by Jon Beniston <jon@beniston.com>
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
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 3 of the License, 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.,
|
||||
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef _ELF_LM32_H
|
||||
#define _ELF_LM32_H
|
||||
|
||||
#include "elf/reloc-macros.h"
|
||||
|
||||
/* Relocations. */
|
||||
START_RELOC_NUMBERS (elf_lm32_reloc_type)
|
||||
RELOC_NUMBER (R_LM32_NONE, 0)
|
||||
RELOC_NUMBER (R_LM32_8, 1)
|
||||
RELOC_NUMBER (R_LM32_16, 2)
|
||||
RELOC_NUMBER (R_LM32_32, 3)
|
||||
RELOC_NUMBER (R_LM32_HI16, 4)
|
||||
RELOC_NUMBER (R_LM32_LO16, 5)
|
||||
RELOC_NUMBER (R_LM32_GPREL16, 6)
|
||||
RELOC_NUMBER (R_LM32_CALL, 7)
|
||||
RELOC_NUMBER (R_LM32_BRANCH, 8)
|
||||
RELOC_NUMBER (R_LM32_GNU_VTINHERIT, 9)
|
||||
RELOC_NUMBER (R_LM32_GNU_VTENTRY, 10)
|
||||
RELOC_NUMBER (R_LM32_16_GOT, 11)
|
||||
RELOC_NUMBER (R_LM32_GOTOFF_HI16, 12)
|
||||
RELOC_NUMBER (R_LM32_GOTOFF_LO16, 13)
|
||||
RELOC_NUMBER (R_LM32_COPY, 14)
|
||||
RELOC_NUMBER (R_LM32_GLOB_DAT, 15)
|
||||
RELOC_NUMBER (R_LM32_JMP_SLOT, 16)
|
||||
RELOC_NUMBER (R_LM32_RELATIVE, 17)
|
||||
END_RELOC_NUMBERS (R_LM32_max)
|
||||
|
||||
/* Processor specific flags for the ELF header e_flags field. */
|
||||
|
||||
#define EF_LM32_MACH 0x00000001
|
||||
|
||||
/* Various CPU types. */
|
||||
|
||||
#define E_LM32_MACH 0x1
|
||||
|
||||
#endif /* _ELF_LM32_H */
|
25
ld/ChangeLog
25
ld/ChangeLog
@ -1,3 +1,12 @@
|
||||
2008-12-23 Jon Beniston <jon@beniston.com>
|
||||
|
||||
* Makefile.am: Add LM32 object files and dependencies.
|
||||
* Makefile.in: Regenate.
|
||||
* NEWS: Record that support for LM32 has been added.
|
||||
* configure.tgt: Add LM32 targets.
|
||||
* emulparams/elf32lm32.sh: New file.
|
||||
* emulparams/elf32lm32fd.sh: New file.
|
||||
|
||||
2008-12-23 Tristan Gingold <gingold@adacore.com>
|
||||
|
||||
* Makefile.am (EXTRA_DIST): Add deffilep.c and deffilep.h
|
||||
@ -43,7 +52,7 @@
|
||||
|
||||
2008-11-27 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
|
||||
|
||||
* emultempl/cr16elf.em (cr16_after_open): New function to handle
|
||||
* emultempl/cr16elf.em (cr16_after_open): New function to handle
|
||||
CR16 ELF embedded reloc creation (ld --embedded-relocs).
|
||||
(check_sections): New function.
|
||||
(LDEMUL_AFTER_OPEN): Define.
|
||||
@ -519,13 +528,13 @@
|
||||
|
||||
2008-07-09 Danny Smith <dannysmith@users.sourceforge.net>
|
||||
|
||||
*pe-dll.c (autofilter_symbolprefixlist): Excude all symbols
|
||||
starting with ".".
|
||||
Exclude "_IMPORT_DESCRIPTOR_".
|
||||
(autofilter_symbolsuffixlist): Exclude "_NULL_THUNK_DATA".
|
||||
(autofilter_symbollist_generic): Don't check for ".text".
|
||||
Exclude "_NULL_IMPORT_DESCRIPTOR".
|
||||
(autofilter_symbollist_i386): Likewise.
|
||||
*pe-dll.c (autofilter_symbolprefixlist): Excude all symbols
|
||||
starting with ".".
|
||||
Exclude "_IMPORT_DESCRIPTOR_".
|
||||
(autofilter_symbolsuffixlist): Exclude "_NULL_THUNK_DATA".
|
||||
(autofilter_symbollist_generic): Don't check for ".text".
|
||||
Exclude "_NULL_IMPORT_DESCRIPTOR".
|
||||
(autofilter_symbollist_i386): Likewise.
|
||||
|
||||
2008-07-07 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
|
@ -180,6 +180,8 @@ ALL_EMULATIONS = \
|
||||
eelf32ip2k.o \
|
||||
eelf32iq2000.o \
|
||||
eelf32iq10.o \
|
||||
eelf32lm32.o \
|
||||
eelf32lm32fd.o \
|
||||
eelf32l4300.o \
|
||||
eelf32lmip.o \
|
||||
eelf32lppc.o \
|
||||
@ -936,6 +938,13 @@ eelf32iq2000.c: $(srcdir)/emulparams/elf32iq2000.sh \
|
||||
eelf32iq10.c: $(srcdir)/emulparams/elf32iq10.sh \
|
||||
$(ELF_GEN_DEPS) $(srcdir)/scripttempl/iq2000.sc ${GEN_DEPENDS}
|
||||
${GENSCRIPTS} elf32iq10 "$(tdir_iq10)"
|
||||
eelf32lm32.c: $(srcdir)/emulparams/elf32lm32.sh \
|
||||
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
|
||||
${GENSCRIPTS} elf32lm32 "$(tdir_elf32lm32)"
|
||||
eelf32lm32fd.c: $(srcdir)/emulparams/elf32lm32fd.sh \
|
||||
$(srcdir)/emulparams/elf32lm32.sh $(ELF_DEPS) \
|
||||
$(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
|
||||
${GENSCRIPTS} elf32lm32fd "$(tdir_elf32lm32fd)"
|
||||
eelf64alpha.c: $(srcdir)/emulparams/elf64alpha.sh \
|
||||
$(ELF_DEPS) $(srcdir)/emultempl/alphaelf.em \
|
||||
$(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
|
||||
|
@ -443,6 +443,8 @@ ALL_EMULATIONS = \
|
||||
eelf32ip2k.o \
|
||||
eelf32iq2000.o \
|
||||
eelf32iq10.o \
|
||||
eelf32lm32.o \
|
||||
eelf32lm32fd.o \
|
||||
eelf32l4300.o \
|
||||
eelf32lmip.o \
|
||||
eelf32lppc.o \
|
||||
@ -1780,6 +1782,13 @@ eelf32iq2000.c: $(srcdir)/emulparams/elf32iq2000.sh \
|
||||
eelf32iq10.c: $(srcdir)/emulparams/elf32iq10.sh \
|
||||
$(ELF_GEN_DEPS) $(srcdir)/scripttempl/iq2000.sc ${GEN_DEPENDS}
|
||||
${GENSCRIPTS} elf32iq10 "$(tdir_iq10)"
|
||||
eelf32lm32.c: $(srcdir)/emulparams/elf32lm32.sh \
|
||||
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
|
||||
${GENSCRIPTS} elf32lm32 "$(tdir_elf32lm32)"
|
||||
eelf32lm32fd.c: $(srcdir)/emulparams/elf32lm32fd.sh \
|
||||
$(srcdir)/emulparams/elf32lm32.sh $(ELF_DEPS) \
|
||||
$(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
|
||||
${GENSCRIPTS} elf32lm32fd "$(tdir_elf32lm32fd)"
|
||||
eelf64alpha.c: $(srcdir)/emulparams/elf64alpha.sh \
|
||||
$(ELF_DEPS) $(srcdir)/emultempl/alphaelf.em \
|
||||
$(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
|
||||
|
2
ld/NEWS
2
ld/NEWS
@ -1,4 +1,6 @@
|
||||
-*- text -*-
|
||||
* Add support for Lattice Mico32 (lm32) architecture.
|
||||
|
||||
* Add CR16 ELF --embedded-relocs (used to embedded relocations into binaries
|
||||
for Embedded-PIC code) option.
|
||||
|
||||
|
@ -301,6 +301,9 @@ ip2k-*-elf) targ_emul=elf32ip2k
|
||||
;;
|
||||
iq2000-*-elf) targ_emul=elf32iq2000 ; targ_extra_emuls="elf32iq10"
|
||||
;;
|
||||
lm32-*-*linux*) targ_emul=elf32lm32fd ;;
|
||||
lm32-*-*) targ_emul=elf32lm32 ; targ_extra_emuls="elf32lm32fd"
|
||||
;;
|
||||
m32c-*-elf | m32c-*-rtems*)
|
||||
targ_emul=elf32m32c
|
||||
;;
|
||||
|
10
ld/emulparams/elf32lm32.sh
Normal file
10
ld/emulparams/elf32lm32.sh
Normal file
@ -0,0 +1,10 @@
|
||||
ARCH=lm32
|
||||
MACHINE=
|
||||
SCRIPT_NAME=elf
|
||||
OUTPUT_FORMAT="elf32-lm32"
|
||||
MAXPAGESIZE=0x1000
|
||||
EMBEDDED=yes
|
||||
TEMPLATE_NAME=elf32
|
||||
TEXT_START_ADDR=0x0000
|
||||
DYNAMIC_LINK=FALSE
|
||||
ALIGNMENT=4
|
16
ld/emulparams/elf32lm32fd.sh
Normal file
16
ld/emulparams/elf32lm32fd.sh
Normal file
@ -0,0 +1,16 @@
|
||||
. ${srcdir}/emulparams/elf32lm32.sh
|
||||
unset STACK_ADDR
|
||||
OUTPUT_FORMAT="elf32-lm32fdpic"
|
||||
MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
|
||||
TEMPLATE_NAME=elf32
|
||||
GENERATE_SHLIB_SCRIPT=yes
|
||||
GENERATE_PIE_SCRIPT=yes
|
||||
EMBEDDED= # This gets us program headers mapped as part of the text segment.
|
||||
OTHER_GOT_SYMBOLS=
|
||||
OTHER_READONLY_SECTIONS="
|
||||
.rofixup : {
|
||||
${RELOCATING+__ROFIXUP_LIST__ = .;}
|
||||
*(.rofixup)
|
||||
${RELOCATING+__ROFIXUP_END__ = .;}
|
||||
}
|
||||
"
|
@ -1,3 +1,7 @@
|
||||
2008-12-23 Jon Beniston <jon@beniston.com>
|
||||
|
||||
* ld-elf/merge.d: Indicate test fails on LM32.
|
||||
|
||||
2008-12-23 Hans-Peter Nilsson <hp@axis.com>
|
||||
|
||||
* lib/ld-lib.exp (run_dump_test): New option ld_after_inputfiles.
|
||||
|
@ -3,7 +3,7 @@
|
||||
#objdump: -s
|
||||
#xfail: "arc-*-*" "avr-*-*" "bfin-*-*" "cris*-*-*" "crx-*-*" "d10v-*-*" "d30v-*-*"
|
||||
#xfail: "dlx-*-*" "fr30-*-*" "frv-*-*" "hppa*-*-*" "h8300-*-*" "score-*-*"
|
||||
#xfail: "i370-*-*" "i860-*-*" "i960-*-*" "ip2k-*-*" "iq2000-*-*"
|
||||
#xfail: "i370-*-*" "i860-*-*" "i960-*-*" "ip2k-*-*" "iq2000-*-*" "lm32-*-*"
|
||||
#xfail: "mcore-*-*" "mn102*-*-*" "mips*-*-*" "ms1-*-*" "msp430-*-*"
|
||||
#xfail: "or32-*-*" "pj-*-*" "sparc*-*-*" "vax-*-*" "xstormy16-*-*" "xtensa*-*-*"
|
||||
|
||||
|
@ -1,3 +1,22 @@
|
||||
2008-12-12 Jon Beniston <jon@beniston.com>
|
||||
|
||||
* Makefile.am: Add LM32 object files and dependencies.
|
||||
* Makefile.in: Regenerate.
|
||||
* configure.in: Add LM32 target.
|
||||
* configure: Regenerate.
|
||||
* disassemble.c: Add LM32 disassembler.
|
||||
* cgen-asm.in: Update copyright year.
|
||||
* cgen-dis.in: Update copyright year.
|
||||
* cgen-ibld.in: Update copyright year.
|
||||
* lm32-asm.c: New file.
|
||||
* lm32-desc.c: New file.
|
||||
* lm32-desc.h: New file.
|
||||
* lm32-dis.c: New file.
|
||||
* lm32-ibld.c: New file.
|
||||
* lm32-opc.c: New file.
|
||||
* lm32-opc.h: New file.
|
||||
* lm32-opinst.c: New file.
|
||||
|
||||
2008-12-23 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* i386-dis.c (EXdS): New.
|
||||
|
@ -442,6 +442,7 @@ CGEN_CPUS = fr30 frv ip2k m32c m32r mep mt openrisc xc16x xstormy16
|
||||
|
||||
if CGEN_MAINT
|
||||
IP2K_DEPS = stamp-ip2k
|
||||
LM32_DEPS = stamp-lm32
|
||||
M32C_DEPS = stamp-m32c
|
||||
M32R_DEPS = stamp-m32r
|
||||
FR30_DEPS = stamp-fr30
|
||||
@ -454,6 +455,7 @@ XC16X_DEPS = stamp-xc16x
|
||||
XSTORMY16_DEPS = stamp-xstormy16
|
||||
else
|
||||
IP2K_DEPS =
|
||||
LM32_DEPS =
|
||||
M32C_DEPS =
|
||||
M32R_DEPS =
|
||||
FR30_DEPS =
|
||||
@ -488,6 +490,14 @@ stamp-ip2k: $(CGENDEPS) $(CPUDIR)/ip2k.cpu $(CPUDIR)/ip2k.opc
|
||||
$(MAKE) run-cgen arch=ip2k prefix=ip2k options= \
|
||||
archfile=$(CPUDIR)/ip2k.cpu opcfile=$(CPUDIR)/ip2k.opc extrafiles=
|
||||
|
||||
$(srcdir)lm32-desc.h $(srcdir)/lm32-desc.c $(srcdir)/lm32-opc.h $(srcdir)/lm32-opc.c $(srcdir)/lm32-ibld.c $(srcdir)/lm32-opinst.c $(srcdir)/lm32-asm.c $(srcdir)/lm32-dis.c: $(LM32_DEPS)
|
||||
@true
|
||||
stamp-lm32: $(CGENDEPS) $(srcdir)/../cpu/lm32.cpu $(srcdir)/../cpu/lm32.opc
|
||||
$(MAKE) run-cgen arch=lm32 prefix=lm32 options=opinst \
|
||||
archfile=$(srcdir)/../cpu/lm32.cpu \
|
||||
opcfile=$(srcdir)/../cpu/lm32.opc \
|
||||
extrafiles=opinst
|
||||
|
||||
$(srcdir)/m32c-desc.h $(srcdir)/m32c-desc.c $(srcdir)/m32c-opc.h $(srcdir)/m32c-opc.c $(srcdir)/m32c-ibld.c $(srcdir)/m32c-asm.c $(srcdir)/m32c-dis.c: $(M32C_DEPS)
|
||||
# @true
|
||||
stamp-m32c: $(CGENDEPS) $(srcdir)/../cpu/m32c.cpu $(srcdir)/../cpu/m32c.opc
|
||||
@ -872,6 +882,26 @@ iq2000-opc.lo: iq2000-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h iq2000-desc.h $(INCDIR)/opcode/cgen-bitset.h \
|
||||
$(INCDIR)/opcode/cgen.h $(INCDIR)/opcode/cgen-bitset.h \
|
||||
iq2000-opc.h $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h
|
||||
lm32-asm.lo: lm32-asm.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h lm32-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
lm32-opc.h opintl.h $(INCDIR)/xregex.h $(INCDIR)/xregex2.h \
|
||||
$(INCDIR)/libiberty.h $(INCDIR)/safe-ctype.h
|
||||
lm32-desc.lo: lm32-desc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h lm32-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
lm32-opc.h opintl.h $(INCDIR)/libiberty.h $(INCDIR)/xregex.h \
|
||||
$(INCDIR)/xregex2.h
|
||||
lm32-dis.lo: lm32-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/libiberty.h \
|
||||
lm32-desc.h $(INCDIR)/opcode/cgen.h lm32-opc.h opintl.h
|
||||
lm32-ibld.lo: lm32-ibld.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h lm32-desc.h \
|
||||
$(INCDIR)/opcode/cgen.h lm32-opc.h opintl.h $(INCDIR)/safe-ctype.h
|
||||
lm32-opc.lo: lm32-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h lm32-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
lm32-opc.h $(INCDIR)/libiberty.h
|
||||
lm32-opinst.lo: lm32-opinst.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h lm32-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
lm32-opc.h
|
||||
m32c-asm.lo: m32c-asm.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h m32c-desc.h $(INCDIR)/opcode/cgen-bitset.h \
|
||||
$(INCDIR)/opcode/cgen.h $(INCDIR)/opcode/cgen-bitset.h \
|
||||
|
@ -634,6 +634,8 @@ CGENDEPS = \
|
||||
CGEN_CPUS = fr30 frv ip2k m32c m32r mep mt openrisc xc16x xstormy16
|
||||
@CGEN_MAINT_FALSE@IP2K_DEPS =
|
||||
@CGEN_MAINT_TRUE@IP2K_DEPS = stamp-ip2k
|
||||
@CGEN_MAINT_FALSE@LM32_DEPS =
|
||||
@CGEN_MAINT_TRUE@LM32_DEPS = stamp-lm32
|
||||
@CGEN_MAINT_FALSE@M32C_DEPS =
|
||||
@CGEN_MAINT_TRUE@M32C_DEPS = stamp-m32c
|
||||
@CGEN_MAINT_FALSE@M32R_DEPS =
|
||||
@ -666,15 +668,15 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
echo ' cd $(srcdir) && $(AUTOMAKE) --cygnus '; \
|
||||
cd $(srcdir) && $(AUTOMAKE) --cygnus \
|
||||
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \
|
||||
cd $(srcdir) && $(AUTOMAKE) --foreign \
|
||||
&& exit 0; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile'; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --cygnus Makefile
|
||||
$(AUTOMAKE) --foreign Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
@ -1053,6 +1055,14 @@ stamp-ip2k: $(CGENDEPS) $(CPUDIR)/ip2k.cpu $(CPUDIR)/ip2k.opc
|
||||
$(MAKE) run-cgen arch=ip2k prefix=ip2k options= \
|
||||
archfile=$(CPUDIR)/ip2k.cpu opcfile=$(CPUDIR)/ip2k.opc extrafiles=
|
||||
|
||||
$(srcdir)lm32-desc.h $(srcdir)/lm32-desc.c $(srcdir)/lm32-opc.h $(srcdir)/lm32-opc.c $(srcdir)/lm32-ibld.c $(srcdir)/lm32-opinst.c $(srcdir)/lm32-asm.c $(srcdir)/lm32-dis.c: $(LM32_DEPS)
|
||||
@true
|
||||
stamp-lm32: $(CGENDEPS) $(srcdir)/../cpu/lm32.cpu $(srcdir)/../cpu/lm32.opc
|
||||
$(MAKE) run-cgen arch=lm32 prefix=lm32 options=opinst \
|
||||
archfile=$(srcdir)/../cpu/lm32.cpu \
|
||||
opcfile=$(srcdir)/../cpu/lm32.opc \
|
||||
extrafiles=opinst
|
||||
|
||||
$(srcdir)/m32c-desc.h $(srcdir)/m32c-desc.c $(srcdir)/m32c-opc.h $(srcdir)/m32c-opc.c $(srcdir)/m32c-ibld.c $(srcdir)/m32c-asm.c $(srcdir)/m32c-dis.c: $(M32C_DEPS)
|
||||
# @true
|
||||
stamp-m32c: $(CGENDEPS) $(srcdir)/../cpu/m32c.cpu $(srcdir)/../cpu/m32c.opc
|
||||
@ -1436,6 +1446,26 @@ iq2000-opc.lo: iq2000-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h iq2000-desc.h $(INCDIR)/opcode/cgen-bitset.h \
|
||||
$(INCDIR)/opcode/cgen.h $(INCDIR)/opcode/cgen-bitset.h \
|
||||
iq2000-opc.h $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h
|
||||
lm32-asm.lo: lm32-asm.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h lm32-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
lm32-opc.h opintl.h $(INCDIR)/xregex.h $(INCDIR)/xregex2.h \
|
||||
$(INCDIR)/libiberty.h $(INCDIR)/safe-ctype.h
|
||||
lm32-desc.lo: lm32-desc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h lm32-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
lm32-opc.h opintl.h $(INCDIR)/libiberty.h $(INCDIR)/xregex.h \
|
||||
$(INCDIR)/xregex2.h
|
||||
lm32-dis.lo: lm32-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/libiberty.h \
|
||||
lm32-desc.h $(INCDIR)/opcode/cgen.h lm32-opc.h opintl.h
|
||||
lm32-ibld.lo: lm32-ibld.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h lm32-desc.h \
|
||||
$(INCDIR)/opcode/cgen.h lm32-opc.h opintl.h $(INCDIR)/safe-ctype.h
|
||||
lm32-opc.lo: lm32-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h lm32-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
lm32-opc.h $(INCDIR)/libiberty.h
|
||||
lm32-opinst.lo: lm32-opinst.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h lm32-desc.h $(INCDIR)/opcode/cgen.h \
|
||||
lm32-opc.h
|
||||
m32c-asm.lo: m32c-asm.c sysdep.h config.h $(INCDIR)/ansidecl.h \
|
||||
$(BFD_H) $(INCDIR)/symcat.h m32c-desc.h $(INCDIR)/opcode/cgen-bitset.h \
|
||||
$(INCDIR)/opcode/cgen.h $(INCDIR)/opcode/cgen-bitset.h \
|
||||
|
@ -4,7 +4,7 @@
|
||||
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, 2005, 2007
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2007, 2008
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of libopcodes.
|
||||
|
@ -4,8 +4,8 @@
|
||||
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, 2002, 2003, 2005, 2007
|
||||
Free Software Foundation, Inc.
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007,
|
||||
2008 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of libopcodes.
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
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, 2005, 2006, 2007
|
||||
Free Software Foundation, Inc.
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2006, 2007,
|
||||
2008 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of libopcodes.
|
||||
|
||||
|
1
opcodes/configure
vendored
1
opcodes/configure
vendored
@ -12533,6 +12533,7 @@ if test x${all_targets} = xfalse ; then
|
||||
bfd_ia64_arch) ta="$ta ia64-dis.lo ia64-opc.lo" ;;
|
||||
bfd_ip2k_arch) ta="$ta ip2k-asm.lo ip2k-desc.lo ip2k-dis.lo ip2k-ibld.lo ip2k-opc.lo" using_cgen=yes ;;
|
||||
bfd_iq2000_arch) ta="$ta iq2000-asm.lo iq2000-desc.lo iq2000-dis.lo iq2000-ibld.lo iq2000-opc.lo" using_cgen=yes ;;
|
||||
bfd_lm32_arch) ta="$ta lm32-asm.lo lm32-desc.lo lm32-dis.lo lm32-ibld.lo lm32-opc.lo lm32-opinst.lo" using_cgen=yes ;;
|
||||
bfd_m32c_arch) ta="$ta m32c-asm.lo m32c-desc.lo m32c-dis.lo m32c-ibld.lo m32c-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" ;;
|
||||
|
@ -200,6 +200,7 @@ if test x${all_targets} = xfalse ; then
|
||||
bfd_ia64_arch) ta="$ta ia64-dis.lo ia64-opc.lo" ;;
|
||||
bfd_ip2k_arch) ta="$ta ip2k-asm.lo ip2k-desc.lo ip2k-dis.lo ip2k-ibld.lo ip2k-opc.lo" using_cgen=yes ;;
|
||||
bfd_iq2000_arch) ta="$ta iq2000-asm.lo iq2000-desc.lo iq2000-dis.lo iq2000-ibld.lo iq2000-opc.lo" using_cgen=yes ;;
|
||||
bfd_lm32_arch) ta="$ta lm32-asm.lo lm32-desc.lo lm32-dis.lo lm32-ibld.lo lm32-opc.lo lm32-opinst.lo" using_cgen=yes ;;
|
||||
bfd_m32c_arch) ta="$ta m32c-asm.lo m32c-desc.lo m32c-dis.lo m32c-ibld.lo m32c-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" ;;
|
||||
|
@ -46,6 +46,7 @@
|
||||
#define ARCH_ia64
|
||||
#define ARCH_ip2k
|
||||
#define ARCH_iq2000
|
||||
#define ARCH_lm32
|
||||
#define ARCH_m32c
|
||||
#define ARCH_m32r
|
||||
#define ARCH_m68hc11
|
||||
@ -223,6 +224,11 @@ disassembler (abfd)
|
||||
disassemble = print_insn_fr30;
|
||||
break;
|
||||
#endif
|
||||
#ifdef ARCH_lm32
|
||||
case bfd_arch_lm32:
|
||||
disassemble = print_insn_lm32;
|
||||
break;
|
||||
#endif
|
||||
#ifdef ARCH_m32r
|
||||
case bfd_arch_m32r:
|
||||
disassemble = print_insn_m32r;
|
||||
|
747
opcodes/lm32-asm.c
Normal file
747
opcodes/lm32-asm.c
Normal file
@ -0,0 +1,747 @@
|
||||
/* 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, 2005, 2007, 2008
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of libopcodes.
|
||||
|
||||
This library 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 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
It 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.,
|
||||
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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 "lm32-desc.h"
|
||||
#include "lm32-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
|
||||
(CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
|
||||
|
||||
/* -- assembler routines inserted here. */
|
||||
|
||||
/* -- asm.c */
|
||||
|
||||
/* Handle signed/unsigned literal. */
|
||||
|
||||
static const char *
|
||||
parse_imm (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
unsigned long *valuep)
|
||||
{
|
||||
const char *errmsg;
|
||||
signed long value;
|
||||
|
||||
errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
|
||||
if (errmsg == NULL)
|
||||
{
|
||||
unsigned long x = value & 0xFFFF0000;
|
||||
if (x != 0 && x != 0xFFFF0000)
|
||||
errmsg = _("immediate value out of range");
|
||||
else
|
||||
*valuep = (value & 0xFFFF);
|
||||
}
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
/* Handle hi() */
|
||||
|
||||
static const char *
|
||||
parse_hi16 (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
unsigned long *valuep)
|
||||
{
|
||||
if (strncasecmp (*strp, "hi(", 3) == 0)
|
||||
{
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
const char *errmsg;
|
||||
|
||||
*strp += 3;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return _("missing `)'");
|
||||
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value = (value >> 16) & 0xffff;
|
||||
*valuep = value;
|
||||
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return parse_imm (cd, strp, opindex, valuep);
|
||||
}
|
||||
|
||||
/* Handle lo() */
|
||||
|
||||
static const char *
|
||||
parse_lo16 (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
unsigned long *valuep)
|
||||
{
|
||||
if (strncasecmp (*strp, "lo(", 3) == 0)
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
*strp += 3;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return _("missing `)'");
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value &= 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return parse_imm (cd, strp, opindex, valuep);
|
||||
}
|
||||
|
||||
/* Handle gp() */
|
||||
|
||||
static const char *
|
||||
parse_gp16 (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
long *valuep)
|
||||
{
|
||||
if (strncasecmp (*strp, "gp(", 3) == 0)
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
*strp += 3;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_GPREL16,
|
||||
& result_type, & value);
|
||||
if (**strp != ')')
|
||||
return _("missing `)'");
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value &= 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return _("expecting gp relative address: gp(symbol)");
|
||||
}
|
||||
|
||||
/* Handle got() */
|
||||
|
||||
static const char *
|
||||
parse_got16 (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
long *valuep)
|
||||
{
|
||||
if (strncasecmp (*strp, "got(", 4) == 0)
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
*strp += 4;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_16_GOT,
|
||||
& result_type, & value);
|
||||
if (**strp != ')')
|
||||
return _("missing `)'");
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value &= 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return _("expecting got relative address: got(symbol)");
|
||||
}
|
||||
|
||||
/* Handle gotoffhi16() */
|
||||
|
||||
static const char *
|
||||
parse_gotoff_hi16 (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
long *valuep)
|
||||
{
|
||||
if (strncasecmp (*strp, "gotoffhi16(", 11) == 0)
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
*strp += 11;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_HI16,
|
||||
& result_type, & value);
|
||||
if (**strp != ')')
|
||||
return _("missing `)'");
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value &= 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return _("expecting got relative address: gotoffhi16(symbol)");
|
||||
}
|
||||
|
||||
/* Handle gotofflo16() */
|
||||
|
||||
static const char *
|
||||
parse_gotoff_lo16 (CGEN_CPU_DESC cd,
|
||||
const char **strp,
|
||||
int opindex,
|
||||
long *valuep)
|
||||
{
|
||||
if (strncasecmp (*strp, "gotofflo16(", 11) == 0)
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
*strp += 11;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_LO16,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return _("missing `)'");
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value &= 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
return _("expecting got relative address: gotofflo16(symbol)");
|
||||
}
|
||||
|
||||
const char * lm32_cgen_parse_operand
|
||||
(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 *
|
||||
lm32_cgen_parse_operand (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 LM32_OPERAND_BRANCH :
|
||||
{
|
||||
bfd_vma value = 0;
|
||||
errmsg = cgen_parse_address (cd, strp, LM32_OPERAND_BRANCH, 0, NULL, & value);
|
||||
fields->f_branch = value;
|
||||
}
|
||||
break;
|
||||
case LM32_OPERAND_CALL :
|
||||
{
|
||||
bfd_vma value = 0;
|
||||
errmsg = cgen_parse_address (cd, strp, LM32_OPERAND_CALL, 0, NULL, & value);
|
||||
fields->f_call = value;
|
||||
}
|
||||
break;
|
||||
case LM32_OPERAND_CSR :
|
||||
errmsg = cgen_parse_keyword (cd, strp, & lm32_cgen_opval_h_csr, & fields->f_csr);
|
||||
break;
|
||||
case LM32_OPERAND_EXCEPTION :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, LM32_OPERAND_EXCEPTION, (unsigned long *) (& fields->f_exception));
|
||||
break;
|
||||
case LM32_OPERAND_GOT16 :
|
||||
errmsg = parse_got16 (cd, strp, LM32_OPERAND_GOT16, (long *) (& fields->f_imm));
|
||||
break;
|
||||
case LM32_OPERAND_GOTOFFHI16 :
|
||||
errmsg = parse_gotoff_hi16 (cd, strp, LM32_OPERAND_GOTOFFHI16, (long *) (& fields->f_imm));
|
||||
break;
|
||||
case LM32_OPERAND_GOTOFFLO16 :
|
||||
errmsg = parse_gotoff_lo16 (cd, strp, LM32_OPERAND_GOTOFFLO16, (long *) (& fields->f_imm));
|
||||
break;
|
||||
case LM32_OPERAND_GP16 :
|
||||
errmsg = parse_gp16 (cd, strp, LM32_OPERAND_GP16, (long *) (& fields->f_imm));
|
||||
break;
|
||||
case LM32_OPERAND_HI16 :
|
||||
errmsg = parse_hi16 (cd, strp, LM32_OPERAND_HI16, (unsigned long *) (& fields->f_uimm));
|
||||
break;
|
||||
case LM32_OPERAND_IMM :
|
||||
errmsg = cgen_parse_signed_integer (cd, strp, LM32_OPERAND_IMM, (long *) (& fields->f_imm));
|
||||
break;
|
||||
case LM32_OPERAND_LO16 :
|
||||
errmsg = parse_lo16 (cd, strp, LM32_OPERAND_LO16, (unsigned long *) (& fields->f_uimm));
|
||||
break;
|
||||
case LM32_OPERAND_R0 :
|
||||
errmsg = cgen_parse_keyword (cd, strp, & lm32_cgen_opval_h_gr, & fields->f_r0);
|
||||
break;
|
||||
case LM32_OPERAND_R1 :
|
||||
errmsg = cgen_parse_keyword (cd, strp, & lm32_cgen_opval_h_gr, & fields->f_r1);
|
||||
break;
|
||||
case LM32_OPERAND_R2 :
|
||||
errmsg = cgen_parse_keyword (cd, strp, & lm32_cgen_opval_h_gr, & fields->f_r2);
|
||||
break;
|
||||
case LM32_OPERAND_SHIFT :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, LM32_OPERAND_SHIFT, (unsigned long *) (& fields->f_shift));
|
||||
break;
|
||||
case LM32_OPERAND_UIMM :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, LM32_OPERAND_UIMM, (unsigned long *) (& fields->f_uimm));
|
||||
break;
|
||||
case LM32_OPERAND_USER :
|
||||
errmsg = cgen_parse_unsigned_integer (cd, strp, LM32_OPERAND_USER, (unsigned long *) (& fields->f_user));
|
||||
break;
|
||||
|
||||
default :
|
||||
/* xgettext:c-format */
|
||||
fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
|
||||
abort ();
|
||||
}
|
||||
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
cgen_parse_fn * const lm32_cgen_parse_handlers[] =
|
||||
{
|
||||
parse_insn_normal,
|
||||
};
|
||||
|
||||
void
|
||||
lm32_cgen_init_asm (CGEN_CPU_DESC cd)
|
||||
{
|
||||
lm32_cgen_init_opcode_table (cd);
|
||||
lm32_cgen_init_ibld_table (cd);
|
||||
cd->parse_handlers = & lm32_cgen_parse_handlers[0];
|
||||
cd->parse_operand = lm32_cgen_parse_operand;
|
||||
#ifdef CGEN_ASM_INIT_HOOK
|
||||
CGEN_ASM_INIT_HOOK
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Regex construction routine.
|
||||
|
||||
This translates an opcode syntax string into a regex string,
|
||||
by replacing any non-character syntax element (such as an
|
||||
opcode) with the pattern '.*'
|
||||
|
||||
It then compiles the regex and stores it in the opcode, for
|
||||
later use by lm32_cgen_assemble_insn
|
||||
|
||||
Returns NULL for success, an error message for failure. */
|
||||
|
||||
char *
|
||||
lm32_cgen_build_insn_regex (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 (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 *
|
||||
lm32_cgen_assemble_insn (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 (! lm32_cgen_insn_supported (cd, insn))
|
||||
continue;
|
||||
#endif
|
||||
/* If the RELAXED 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_RELAXED) != 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;
|
||||
}
|
||||
}
|
1183
opcodes/lm32-desc.c
Normal file
1183
opcodes/lm32-desc.c
Normal file
File diff suppressed because it is too large
Load Diff
246
opcodes/lm32-desc.h
Normal file
246
opcodes/lm32-desc.h
Normal file
@ -0,0 +1,246 @@
|
||||
/* CPU data header for lm32.
|
||||
|
||||
THIS FILE IS MACHINE GENERATED WITH CGEN.
|
||||
|
||||
Copyright 1996-2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
|
||||
|
||||
This file 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 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
It 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.,
|
||||
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef LM32_CPU_H
|
||||
#define LM32_CPU_H
|
||||
|
||||
#include "opcode/cgen-bitset.h"
|
||||
|
||||
#define CGEN_ARCH lm32
|
||||
|
||||
/* Given symbol S, return lm32_cgen_<S>. */
|
||||
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
|
||||
#define CGEN_SYM(s) lm32##_cgen_##s
|
||||
#else
|
||||
#define CGEN_SYM(s) lm32/**/_cgen_/**/s
|
||||
#endif
|
||||
|
||||
|
||||
/* Selected cpu families. */
|
||||
#define HAVE_CPU_LM32BF
|
||||
|
||||
#define CGEN_INSN_LSB0_P 1
|
||||
|
||||
/* Minimum size of any insn (in bytes). */
|
||||
#define CGEN_MIN_INSN_SIZE 4
|
||||
|
||||
/* Maximum size of any insn (in bytes). */
|
||||
#define CGEN_MAX_INSN_SIZE 4
|
||||
|
||||
#define CGEN_INT_INSN_P 1
|
||||
|
||||
/* Maximum number of syntax elements in an instruction. */
|
||||
#define CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS 15
|
||||
|
||||
/* 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 5
|
||||
|
||||
/* Enums. */
|
||||
|
||||
/* Enum declaration for opcodes. */
|
||||
typedef enum opcodes {
|
||||
OP_ADD = 45, OP_ADDI = 13, OP_AND = 40, OP_ANDI = 8
|
||||
, OP_ANDHI = 24, OP_B = 48, OP_BI = 56, OP_BE = 17
|
||||
, OP_BG = 18, OP_BGE = 19, OP_BGEU = 20, OP_BGU = 21
|
||||
, OP_BNE = 23, OP_CALL = 54, OP_CALLI = 62, OP_CMPE = 57
|
||||
, OP_CMPEI = 25, OP_CMPG = 58, OP_CMPGI = 26, OP_CMPGE = 59
|
||||
, OP_CMPGEI = 27, OP_CMPGEU = 60, OP_CMPGEUI = 28, OP_CMPGU = 61
|
||||
, OP_CMPGUI = 29, OP_CMPNE = 63, OP_CMPNEI = 31, OP_DIVU = 35
|
||||
, OP_LB = 4, OP_LBU = 16, OP_LH = 7, OP_LHU = 11
|
||||
, OP_LW = 10, OP_MODU = 49, OP_MUL = 34, OP_MULI = 2
|
||||
, OP_NOR = 33, OP_NORI = 1, OP_OR = 46, OP_ORI = 14
|
||||
, OP_ORHI = 30, OP_RAISE = 43, OP_RCSR = 36, OP_SB = 12
|
||||
, OP_SEXTB = 44, OP_SEXTH = 55, OP_SH = 3, OP_SL = 47
|
||||
, OP_SLI = 15, OP_SR = 37, OP_SRI = 5, OP_SRU = 32
|
||||
, OP_SRUI = 0, OP_SUB = 50, OP_SW = 22, OP_USER = 51
|
||||
, OP_WCSR = 52, OP_XNOR = 41, OP_XNORI = 9, OP_XOR = 38
|
||||
, OP_XORI = 6
|
||||
} OPCODES;
|
||||
|
||||
/* Attributes. */
|
||||
|
||||
/* Enum declaration for machine type selection. */
|
||||
typedef enum mach_attr {
|
||||
MACH_BASE, MACH_LM32, MACH_MAX
|
||||
} MACH_ATTR;
|
||||
|
||||
/* Enum declaration for instruction set selection. */
|
||||
typedef enum isa_attr {
|
||||
ISA_LM32, ISA_MAX
|
||||
} ISA_ATTR;
|
||||
|
||||
/* Number of architecture variants. */
|
||||
#define MAX_ISAS 1
|
||||
#define MAX_MACHS ((int) MACH_MAX)
|
||||
|
||||
/* Ifield support. */
|
||||
|
||||
/* 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)
|
||||
|
||||
/* cgen_ifld attribute accessor macros. */
|
||||
#define CGEN_ATTR_CGEN_IFLD_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_IFLD_MACH-CGEN_IFLD_START_NBOOLS-1].nonbitset)
|
||||
#define CGEN_ATTR_CGEN_IFLD_VIRTUAL_VALUE(attrs) (((attrs)->bool & (1 << CGEN_IFLD_VIRTUAL)) != 0)
|
||||
#define CGEN_ATTR_CGEN_IFLD_PCREL_ADDR_VALUE(attrs) (((attrs)->bool & (1 << CGEN_IFLD_PCREL_ADDR)) != 0)
|
||||
#define CGEN_ATTR_CGEN_IFLD_ABS_ADDR_VALUE(attrs) (((attrs)->bool & (1 << CGEN_IFLD_ABS_ADDR)) != 0)
|
||||
#define CGEN_ATTR_CGEN_IFLD_RESERVED_VALUE(attrs) (((attrs)->bool & (1 << CGEN_IFLD_RESERVED)) != 0)
|
||||
#define CGEN_ATTR_CGEN_IFLD_SIGN_OPT_VALUE(attrs) (((attrs)->bool & (1 << CGEN_IFLD_SIGN_OPT)) != 0)
|
||||
#define CGEN_ATTR_CGEN_IFLD_SIGNED_VALUE(attrs) (((attrs)->bool & (1 << CGEN_IFLD_SIGNED)) != 0)
|
||||
|
||||
/* Enum declaration for lm32 ifield types. */
|
||||
typedef enum ifield_type {
|
||||
LM32_F_NIL, LM32_F_ANYOF, LM32_F_OPCODE, LM32_F_R0
|
||||
, LM32_F_R1, LM32_F_R2, LM32_F_RESV0, LM32_F_SHIFT
|
||||
, LM32_F_IMM, LM32_F_UIMM, LM32_F_CSR, LM32_F_USER
|
||||
, LM32_F_EXCEPTION, LM32_F_BRANCH, LM32_F_CALL, LM32_F_MAX
|
||||
} IFIELD_TYPE;
|
||||
|
||||
#define MAX_IFLD ((int) LM32_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)
|
||||
|
||||
/* cgen_hw attribute accessor macros. */
|
||||
#define CGEN_ATTR_CGEN_HW_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_HW_MACH-CGEN_HW_START_NBOOLS-1].nonbitset)
|
||||
#define CGEN_ATTR_CGEN_HW_VIRTUAL_VALUE(attrs) (((attrs)->bool & (1 << CGEN_HW_VIRTUAL)) != 0)
|
||||
#define CGEN_ATTR_CGEN_HW_CACHE_ADDR_VALUE(attrs) (((attrs)->bool & (1 << CGEN_HW_CACHE_ADDR)) != 0)
|
||||
#define CGEN_ATTR_CGEN_HW_PC_VALUE(attrs) (((attrs)->bool & (1 << CGEN_HW_PC)) != 0)
|
||||
#define CGEN_ATTR_CGEN_HW_PROFILE_VALUE(attrs) (((attrs)->bool & (1 << CGEN_HW_PROFILE)) != 0)
|
||||
|
||||
/* Enum declaration for lm32 hardware types. */
|
||||
typedef enum cgen_hw_type {
|
||||
HW_H_MEMORY, HW_H_SINT, HW_H_UINT, HW_H_ADDR
|
||||
, HW_H_IADDR, HW_H_PC, HW_H_GR, HW_H_CSR
|
||||
, 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)
|
||||
|
||||
/* cgen_operand attribute accessor macros. */
|
||||
#define CGEN_ATTR_CGEN_OPERAND_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_OPERAND_MACH-CGEN_OPERAND_START_NBOOLS-1].nonbitset)
|
||||
#define CGEN_ATTR_CGEN_OPERAND_VIRTUAL_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_VIRTUAL)) != 0)
|
||||
#define CGEN_ATTR_CGEN_OPERAND_PCREL_ADDR_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_PCREL_ADDR)) != 0)
|
||||
#define CGEN_ATTR_CGEN_OPERAND_ABS_ADDR_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_ABS_ADDR)) != 0)
|
||||
#define CGEN_ATTR_CGEN_OPERAND_SIGN_OPT_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_SIGN_OPT)) != 0)
|
||||
#define CGEN_ATTR_CGEN_OPERAND_SIGNED_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_SIGNED)) != 0)
|
||||
#define CGEN_ATTR_CGEN_OPERAND_NEGATIVE_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_NEGATIVE)) != 0)
|
||||
#define CGEN_ATTR_CGEN_OPERAND_RELAX_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_RELAX)) != 0)
|
||||
#define CGEN_ATTR_CGEN_OPERAND_SEM_ONLY_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_SEM_ONLY)) != 0)
|
||||
|
||||
/* Enum declaration for lm32 operand types. */
|
||||
typedef enum cgen_operand_type {
|
||||
LM32_OPERAND_PC, LM32_OPERAND_R0, LM32_OPERAND_R1, LM32_OPERAND_R2
|
||||
, LM32_OPERAND_SHIFT, LM32_OPERAND_IMM, LM32_OPERAND_UIMM, LM32_OPERAND_BRANCH
|
||||
, LM32_OPERAND_CALL, LM32_OPERAND_CSR, LM32_OPERAND_USER, LM32_OPERAND_EXCEPTION
|
||||
, LM32_OPERAND_HI16, LM32_OPERAND_LO16, LM32_OPERAND_GP16, LM32_OPERAND_GOT16
|
||||
, LM32_OPERAND_GOTOFFHI16, LM32_OPERAND_GOTOFFLO16, LM32_OPERAND_MAX
|
||||
} CGEN_OPERAND_TYPE;
|
||||
|
||||
/* Number of operands types. */
|
||||
#define MAX_OPERANDS 18
|
||||
|
||||
/* Maximum number of operands referenced by any insn. */
|
||||
#define MAX_OPERAND_INSTANCES 5
|
||||
|
||||
/* 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_RELAXED
|
||||
, CGEN_INSN_NO_DIS, CGEN_INSN_PBB, 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_insn attribute accessor macros. */
|
||||
#define CGEN_ATTR_CGEN_INSN_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_INSN_MACH-CGEN_INSN_START_NBOOLS-1].nonbitset)
|
||||
#define CGEN_ATTR_CGEN_INSN_ALIAS_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_ALIAS)) != 0)
|
||||
#define CGEN_ATTR_CGEN_INSN_VIRTUAL_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_VIRTUAL)) != 0)
|
||||
#define CGEN_ATTR_CGEN_INSN_UNCOND_CTI_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_UNCOND_CTI)) != 0)
|
||||
#define CGEN_ATTR_CGEN_INSN_COND_CTI_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_COND_CTI)) != 0)
|
||||
#define CGEN_ATTR_CGEN_INSN_SKIP_CTI_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_SKIP_CTI)) != 0)
|
||||
#define CGEN_ATTR_CGEN_INSN_DELAY_SLOT_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_DELAY_SLOT)) != 0)
|
||||
#define CGEN_ATTR_CGEN_INSN_RELAXABLE_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_RELAXABLE)) != 0)
|
||||
#define CGEN_ATTR_CGEN_INSN_RELAXED_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_RELAXED)) != 0)
|
||||
#define CGEN_ATTR_CGEN_INSN_NO_DIS_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_NO_DIS)) != 0)
|
||||
#define CGEN_ATTR_CGEN_INSN_PBB_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_PBB)) != 0)
|
||||
|
||||
/* cgen.h uses things we just defined. */
|
||||
#include "opcode/cgen.h"
|
||||
|
||||
extern const struct cgen_ifld lm32_cgen_ifld_table[];
|
||||
|
||||
/* Attributes. */
|
||||
extern const CGEN_ATTR_TABLE lm32_cgen_hardware_attr_table[];
|
||||
extern const CGEN_ATTR_TABLE lm32_cgen_ifield_attr_table[];
|
||||
extern const CGEN_ATTR_TABLE lm32_cgen_operand_attr_table[];
|
||||
extern const CGEN_ATTR_TABLE lm32_cgen_insn_attr_table[];
|
||||
|
||||
/* Hardware decls. */
|
||||
|
||||
extern CGEN_KEYWORD lm32_cgen_opval_h_gr;
|
||||
extern CGEN_KEYWORD lm32_cgen_opval_h_csr;
|
||||
|
||||
extern const CGEN_HW_ENTRY lm32_cgen_hw_table[];
|
||||
|
||||
|
||||
|
||||
#endif /* LM32_CPU_H */
|
576
opcodes/lm32-dis.c
Normal file
576
opcodes/lm32-dis.c
Normal file
@ -0,0 +1,576 @@
|
||||
/* 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, 2002, 2003, 2005, 2007,
|
||||
2008 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of libopcodes.
|
||||
|
||||
This library 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 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
It 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.,
|
||||
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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 "libiberty.h"
|
||||
#include "lm32-desc.h"
|
||||
#include "lm32-opc.h"
|
||||
#include "opintl.h"
|
||||
|
||||
/* Default text to print if an instruction isn't recognized. */
|
||||
#define UNKNOWN_INSN_MSG _("*unknown*")
|
||||
|
||||
static void print_normal
|
||||
(CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
|
||||
static void print_address
|
||||
(CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED;
|
||||
static void print_keyword
|
||||
(CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED;
|
||||
static void print_insn_normal
|
||||
(CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int);
|
||||
static int print_insn
|
||||
(CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, unsigned);
|
||||
static int default_print_insn
|
||||
(CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED;
|
||||
static int read_insn
|
||||
(CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *,
|
||||
unsigned long *);
|
||||
|
||||
/* -- disassembler routines inserted here. */
|
||||
|
||||
|
||||
void lm32_cgen_print_operand
|
||||
(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
|
||||
lm32_cgen_print_operand (CGEN_CPU_DESC cd,
|
||||
int opindex,
|
||||
void * xinfo,
|
||||
CGEN_FIELDS *fields,
|
||||
void const *attrs ATTRIBUTE_UNUSED,
|
||||
bfd_vma pc,
|
||||
int length)
|
||||
{
|
||||
disassemble_info *info = (disassemble_info *) xinfo;
|
||||
|
||||
switch (opindex)
|
||||
{
|
||||
case LM32_OPERAND_BRANCH :
|
||||
print_address (cd, info, fields->f_branch, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
|
||||
break;
|
||||
case LM32_OPERAND_CALL :
|
||||
print_address (cd, info, fields->f_call, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
|
||||
break;
|
||||
case LM32_OPERAND_CSR :
|
||||
print_keyword (cd, info, & lm32_cgen_opval_h_csr, fields->f_csr, 0);
|
||||
break;
|
||||
case LM32_OPERAND_EXCEPTION :
|
||||
print_normal (cd, info, fields->f_exception, 0, pc, length);
|
||||
break;
|
||||
case LM32_OPERAND_GOT16 :
|
||||
print_normal (cd, info, fields->f_imm, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
|
||||
break;
|
||||
case LM32_OPERAND_GOTOFFHI16 :
|
||||
print_normal (cd, info, fields->f_imm, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
|
||||
break;
|
||||
case LM32_OPERAND_GOTOFFLO16 :
|
||||
print_normal (cd, info, fields->f_imm, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
|
||||
break;
|
||||
case LM32_OPERAND_GP16 :
|
||||
print_normal (cd, info, fields->f_imm, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
|
||||
break;
|
||||
case LM32_OPERAND_HI16 :
|
||||
print_normal (cd, info, fields->f_uimm, 0, pc, length);
|
||||
break;
|
||||
case LM32_OPERAND_IMM :
|
||||
print_normal (cd, info, fields->f_imm, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
|
||||
break;
|
||||
case LM32_OPERAND_LO16 :
|
||||
print_normal (cd, info, fields->f_uimm, 0, pc, length);
|
||||
break;
|
||||
case LM32_OPERAND_R0 :
|
||||
print_keyword (cd, info, & lm32_cgen_opval_h_gr, fields->f_r0, 0);
|
||||
break;
|
||||
case LM32_OPERAND_R1 :
|
||||
print_keyword (cd, info, & lm32_cgen_opval_h_gr, fields->f_r1, 0);
|
||||
break;
|
||||
case LM32_OPERAND_R2 :
|
||||
print_keyword (cd, info, & lm32_cgen_opval_h_gr, fields->f_r2, 0);
|
||||
break;
|
||||
case LM32_OPERAND_SHIFT :
|
||||
print_normal (cd, info, fields->f_shift, 0, pc, length);
|
||||
break;
|
||||
case LM32_OPERAND_UIMM :
|
||||
print_normal (cd, info, fields->f_uimm, 0, pc, length);
|
||||
break;
|
||||
case LM32_OPERAND_USER :
|
||||
print_normal (cd, info, fields->f_user, 0, pc, length);
|
||||
break;
|
||||
|
||||
default :
|
||||
/* xgettext:c-format */
|
||||
fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
|
||||
opindex);
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
cgen_print_fn * const lm32_cgen_print_handlers[] =
|
||||
{
|
||||
print_insn_normal,
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
lm32_cgen_init_dis (CGEN_CPU_DESC cd)
|
||||
{
|
||||
lm32_cgen_init_opcode_table (cd);
|
||||
lm32_cgen_init_ibld_table (cd);
|
||||
cd->print_handlers = & lm32_cgen_print_handlers[0];
|
||||
cd->print_operand = lm32_cgen_print_operand;
|
||||
}
|
||||
|
||||
|
||||
/* Default print handler. */
|
||||
|
||||
static void
|
||||
print_normal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
|
||||
void *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 (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
|
||||
void *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 (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
|
||||
void *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 `void *' so the disassembler needn't know anything
|
||||
about disassemble_info. */
|
||||
|
||||
static void
|
||||
print_insn_normal (CGEN_CPU_DESC cd,
|
||||
void *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. */
|
||||
lm32_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 (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
|
||||
bfd_vma pc,
|
||||
disassemble_info *info,
|
||||
bfd_byte *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 (CGEN_CPU_DESC cd,
|
||||
bfd_vma pc,
|
||||
disassemble_info *info,
|
||||
bfd_byte *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, (char *) 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 (! lm32_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 (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
|
||||
{
|
||||
bfd_byte 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;
|
||||
CGEN_BITSET *isa;
|
||||
int mach;
|
||||
int endian;
|
||||
CGEN_CPU_DESC cd;
|
||||
} cpu_desc_list;
|
||||
|
||||
int
|
||||
print_insn_lm32 (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 CGEN_BITSET *prev_isa;
|
||||
static int prev_mach;
|
||||
static int prev_endian;
|
||||
int length;
|
||||
CGEN_BITSET *isa;
|
||||
int 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_lm32
|
||||
#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
|
||||
{
|
||||
static CGEN_BITSET *permanent_isa;
|
||||
|
||||
if (!permanent_isa)
|
||||
permanent_isa = cgen_bitset_create (MAX_ISAS);
|
||||
isa = permanent_isa;
|
||||
cgen_bitset_clear (isa);
|
||||
cgen_bitset_add (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
|
||||
&& (cgen_bitset_compare (isa, prev_isa) != 0
|
||||
|| mach != prev_mach
|
||||
|| endian != prev_endian))
|
||||
{
|
||||
cd = 0;
|
||||
for (cl = cd_list; cl; cl = cl->next)
|
||||
{
|
||||
if (cgen_bitset_compare (cl->isa, isa) == 0 &&
|
||||
cl->mach == mach &&
|
||||
cl->endian == endian)
|
||||
{
|
||||
cd = cl->cd;
|
||||
prev_isa = cd->isas;
|
||||
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 = cgen_bitset_copy (isa);
|
||||
prev_mach = mach;
|
||||
prev_endian = endian;
|
||||
cd = lm32_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 = prev_isa;
|
||||
cl->mach = mach;
|
||||
cl->endian = endian;
|
||||
cl->next = cd_list;
|
||||
cd_list = cl;
|
||||
|
||||
lm32_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;
|
||||
}
|
1061
opcodes/lm32-ibld.c
Normal file
1061
opcodes/lm32-ibld.c
Normal file
File diff suppressed because it is too large
Load Diff
876
opcodes/lm32-opc.c
Normal file
876
opcodes/lm32-opc.c
Normal file
@ -0,0 +1,876 @@
|
||||
/* Instruction opcode table for lm32.
|
||||
|
||||
THIS FILE IS MACHINE GENERATED WITH CGEN.
|
||||
|
||||
Copyright 1996-2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
|
||||
|
||||
This file 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 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
It 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.,
|
||||
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "sysdep.h"
|
||||
#include "ansidecl.h"
|
||||
#include "bfd.h"
|
||||
#include "symcat.h"
|
||||
#include "lm32-desc.h"
|
||||
#include "lm32-opc.h"
|
||||
#include "libiberty.h"
|
||||
|
||||
/* The hash functions are recorded here to help keep assembler code out of
|
||||
the disassembler and vice versa. */
|
||||
|
||||
static int asm_hash_insn_p (const CGEN_INSN *);
|
||||
static unsigned int asm_hash_insn (const char *);
|
||||
static int dis_hash_insn_p (const CGEN_INSN *);
|
||||
static unsigned int dis_hash_insn (const char *, CGEN_INSN_INT);
|
||||
|
||||
/* Instruction formats. */
|
||||
|
||||
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
|
||||
#define F(f) & lm32_cgen_ifld_table[LM32_##f]
|
||||
#else
|
||||
#define F(f) & lm32_cgen_ifld_table[LM32_/**/f]
|
||||
#endif
|
||||
static const CGEN_IFMT ifmt_empty ATTRIBUTE_UNUSED = {
|
||||
0, 0, 0x0, { { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_add ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc0007ff, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_R2) }, { F (F_RESV0) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_addi ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_IMM) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_andi ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_UIMM) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_andhii ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_UIMM) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_b ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc1fffff, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_R2) }, { F (F_RESV0) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_bi ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_CALL) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_be ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_BRANCH) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_ori ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_UIMM) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_rcsr ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc1f07ff, { { F (F_OPCODE) }, { F (F_CSR) }, { F (F_R1) }, { F (F_R2) }, { F (F_RESV0) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_sextb ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc1f07ff, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_R2) }, { F (F_RESV0) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_user ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_R2) }, { F (F_USER) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_wcsr ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc00ffff, { { F (F_OPCODE) }, { F (F_CSR) }, { F (F_R1) }, { F (F_R2) }, { F (F_RESV0) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_break ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xffffffff, { { F (F_OPCODE) }, { F (F_EXCEPTION) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_bret ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xffffffff, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_R2) }, { F (F_RESV0) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_mvi ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xffe00000, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_IMM) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_mvui ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xffe00000, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_UIMM) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_mvhi ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xffe00000, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_UIMM) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_mva ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xffe00000, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_IMM) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_nop ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xffffffff, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_IMM) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_lwgotrel ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xffe00000, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_IMM) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_orhigotoffi ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_IMM) }, { 0 } }
|
||||
};
|
||||
|
||||
static const CGEN_IFMT ifmt_addgotoff ATTRIBUTE_UNUSED = {
|
||||
32, 32, 0xfc000000, { { F (F_OPCODE) }, { F (F_R0) }, { F (F_R1) }, { F (F_IMM) }, { 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) LM32_OPERAND_##op
|
||||
#else
|
||||
#define OPERAND(op) LM32_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 lm32_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}},
|
||||
/* add $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0xb4000000 }
|
||||
},
|
||||
/* addi $r1,$r0,$imm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (IMM), 0 } },
|
||||
& ifmt_addi, { 0x34000000 }
|
||||
},
|
||||
/* and $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0xa0000000 }
|
||||
},
|
||||
/* andi $r1,$r0,$uimm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (UIMM), 0 } },
|
||||
& ifmt_andi, { 0x20000000 }
|
||||
},
|
||||
/* andhi $r1,$r0,$hi16 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (HI16), 0 } },
|
||||
& ifmt_andhii, { 0x60000000 }
|
||||
},
|
||||
/* b $r0 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R0), 0 } },
|
||||
& ifmt_b, { 0xc0000000 }
|
||||
},
|
||||
/* bi $call */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (CALL), 0 } },
|
||||
& ifmt_bi, { 0xe0000000 }
|
||||
},
|
||||
/* be $r0,$r1,$branch */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R0), ',', OP (R1), ',', OP (BRANCH), 0 } },
|
||||
& ifmt_be, { 0x44000000 }
|
||||
},
|
||||
/* bg $r0,$r1,$branch */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R0), ',', OP (R1), ',', OP (BRANCH), 0 } },
|
||||
& ifmt_be, { 0x48000000 }
|
||||
},
|
||||
/* bge $r0,$r1,$branch */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R0), ',', OP (R1), ',', OP (BRANCH), 0 } },
|
||||
& ifmt_be, { 0x4c000000 }
|
||||
},
|
||||
/* bgeu $r0,$r1,$branch */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R0), ',', OP (R1), ',', OP (BRANCH), 0 } },
|
||||
& ifmt_be, { 0x50000000 }
|
||||
},
|
||||
/* bgu $r0,$r1,$branch */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R0), ',', OP (R1), ',', OP (BRANCH), 0 } },
|
||||
& ifmt_be, { 0x54000000 }
|
||||
},
|
||||
/* bne $r0,$r1,$branch */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R0), ',', OP (R1), ',', OP (BRANCH), 0 } },
|
||||
& ifmt_be, { 0x5c000000 }
|
||||
},
|
||||
/* call $r0 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R0), 0 } },
|
||||
& ifmt_b, { 0xd8000000 }
|
||||
},
|
||||
/* calli $call */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (CALL), 0 } },
|
||||
& ifmt_bi, { 0xf8000000 }
|
||||
},
|
||||
/* cmpe $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0xe4000000 }
|
||||
},
|
||||
/* cmpei $r1,$r0,$imm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (IMM), 0 } },
|
||||
& ifmt_addi, { 0x64000000 }
|
||||
},
|
||||
/* cmpg $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0xe8000000 }
|
||||
},
|
||||
/* cmpgi $r1,$r0,$imm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (IMM), 0 } },
|
||||
& ifmt_addi, { 0x68000000 }
|
||||
},
|
||||
/* cmpge $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0xec000000 }
|
||||
},
|
||||
/* cmpgei $r1,$r0,$imm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (IMM), 0 } },
|
||||
& ifmt_addi, { 0x6c000000 }
|
||||
},
|
||||
/* cmpgeu $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0xf0000000 }
|
||||
},
|
||||
/* cmpgeui $r1,$r0,$uimm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (UIMM), 0 } },
|
||||
& ifmt_andi, { 0x70000000 }
|
||||
},
|
||||
/* cmpgu $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0xf4000000 }
|
||||
},
|
||||
/* cmpgui $r1,$r0,$uimm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (UIMM), 0 } },
|
||||
& ifmt_andi, { 0x74000000 }
|
||||
},
|
||||
/* cmpne $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0xfc000000 }
|
||||
},
|
||||
/* cmpnei $r1,$r0,$imm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (IMM), 0 } },
|
||||
& ifmt_addi, { 0x7c000000 }
|
||||
},
|
||||
/* divu $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0x8c000000 }
|
||||
},
|
||||
/* lb $r1,($r0+$imm) */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', '(', OP (R0), '+', OP (IMM), ')', 0 } },
|
||||
& ifmt_addi, { 0x10000000 }
|
||||
},
|
||||
/* lbu $r1,($r0+$imm) */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', '(', OP (R0), '+', OP (IMM), ')', 0 } },
|
||||
& ifmt_addi, { 0x40000000 }
|
||||
},
|
||||
/* lh $r1,($r0+$imm) */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', '(', OP (R0), '+', OP (IMM), ')', 0 } },
|
||||
& ifmt_addi, { 0x1c000000 }
|
||||
},
|
||||
/* lhu $r1,($r0+$imm) */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', '(', OP (R0), '+', OP (IMM), ')', 0 } },
|
||||
& ifmt_addi, { 0x2c000000 }
|
||||
},
|
||||
/* lw $r1,($r0+$imm) */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', '(', OP (R0), '+', OP (IMM), ')', 0 } },
|
||||
& ifmt_addi, { 0x28000000 }
|
||||
},
|
||||
/* modu $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0xc4000000 }
|
||||
},
|
||||
/* mul $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0x88000000 }
|
||||
},
|
||||
/* muli $r1,$r0,$imm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (IMM), 0 } },
|
||||
& ifmt_addi, { 0x8000000 }
|
||||
},
|
||||
/* nor $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0x84000000 }
|
||||
},
|
||||
/* nori $r1,$r0,$uimm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (UIMM), 0 } },
|
||||
& ifmt_andi, { 0x4000000 }
|
||||
},
|
||||
/* or $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0xb8000000 }
|
||||
},
|
||||
/* ori $r1,$r0,$lo16 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (LO16), 0 } },
|
||||
& ifmt_ori, { 0x38000000 }
|
||||
},
|
||||
/* orhi $r1,$r0,$hi16 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (HI16), 0 } },
|
||||
& ifmt_andhii, { 0x78000000 }
|
||||
},
|
||||
/* rcsr $r2,$csr */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (CSR), 0 } },
|
||||
& ifmt_rcsr, { 0x90000000 }
|
||||
},
|
||||
/* sb ($r0+$imm),$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', '(', OP (R0), '+', OP (IMM), ')', ',', OP (R1), 0 } },
|
||||
& ifmt_addi, { 0x30000000 }
|
||||
},
|
||||
/* sextb $r2,$r0 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), 0 } },
|
||||
& ifmt_sextb, { 0xb0000000 }
|
||||
},
|
||||
/* sexth $r2,$r0 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), 0 } },
|
||||
& ifmt_sextb, { 0xdc000000 }
|
||||
},
|
||||
/* sh ($r0+$imm),$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', '(', OP (R0), '+', OP (IMM), ')', ',', OP (R1), 0 } },
|
||||
& ifmt_addi, { 0xc000000 }
|
||||
},
|
||||
/* sl $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0xbc000000 }
|
||||
},
|
||||
/* sli $r1,$r0,$imm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (IMM), 0 } },
|
||||
& ifmt_addi, { 0x3c000000 }
|
||||
},
|
||||
/* sr $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0x94000000 }
|
||||
},
|
||||
/* sri $r1,$r0,$imm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (IMM), 0 } },
|
||||
& ifmt_addi, { 0x14000000 }
|
||||
},
|
||||
/* sru $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0x80000000 }
|
||||
},
|
||||
/* srui $r1,$r0,$imm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (IMM), 0 } },
|
||||
& ifmt_addi, { 0x0 }
|
||||
},
|
||||
/* sub $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0xc8000000 }
|
||||
},
|
||||
/* sw ($r0+$imm),$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', '(', OP (R0), '+', OP (IMM), ')', ',', OP (R1), 0 } },
|
||||
& ifmt_addi, { 0x58000000 }
|
||||
},
|
||||
/* user $r2,$r0,$r1,$user */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), ',', OP (USER), 0 } },
|
||||
& ifmt_user, { 0xcc000000 }
|
||||
},
|
||||
/* wcsr $csr,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (CSR), ',', OP (R1), 0 } },
|
||||
& ifmt_wcsr, { 0xd0000000 }
|
||||
},
|
||||
/* xor $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0x98000000 }
|
||||
},
|
||||
/* xori $r1,$r0,$uimm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (UIMM), 0 } },
|
||||
& ifmt_andi, { 0x18000000 }
|
||||
},
|
||||
/* xnor $r2,$r0,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), ',', OP (R1), 0 } },
|
||||
& ifmt_add, { 0xa4000000 }
|
||||
},
|
||||
/* xnori $r1,$r0,$uimm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (UIMM), 0 } },
|
||||
& ifmt_andi, { 0x24000000 }
|
||||
},
|
||||
/* break */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, 0 } },
|
||||
& ifmt_break, { 0xac000002 }
|
||||
},
|
||||
/* scall */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, 0 } },
|
||||
& ifmt_break, { 0xac000007 }
|
||||
},
|
||||
/* bret */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, 0 } },
|
||||
& ifmt_bret, { 0xc3e00000 }
|
||||
},
|
||||
/* eret */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, 0 } },
|
||||
& ifmt_bret, { 0xc3c00000 }
|
||||
},
|
||||
/* ret */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, 0 } },
|
||||
& ifmt_bret, { 0xc3a00000 }
|
||||
},
|
||||
/* mv $r2,$r0 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), 0 } },
|
||||
& ifmt_sextb, { 0xb8000000 }
|
||||
},
|
||||
/* mvi $r1,$imm */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (IMM), 0 } },
|
||||
& ifmt_mvi, { 0x34000000 }
|
||||
},
|
||||
/* mvu $r1,$lo16 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (LO16), 0 } },
|
||||
& ifmt_mvui, { 0x38000000 }
|
||||
},
|
||||
/* mvhi $r1,$hi16 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (HI16), 0 } },
|
||||
& ifmt_mvhi, { 0x78000000 }
|
||||
},
|
||||
/* mva $r1,$gp16 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (GP16), 0 } },
|
||||
& ifmt_mva, { 0x37400000 }
|
||||
},
|
||||
/* not $r2,$r0 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R2), ',', OP (R0), 0 } },
|
||||
& ifmt_sextb, { 0xa4000000 }
|
||||
},
|
||||
/* nop */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, 0 } },
|
||||
& ifmt_nop, { 0x34000000 }
|
||||
},
|
||||
/* lb $r1,$gp16 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (GP16), 0 } },
|
||||
& ifmt_mva, { 0x13400000 }
|
||||
},
|
||||
/* lbu $r1,$gp16 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (GP16), 0 } },
|
||||
& ifmt_mva, { 0x43400000 }
|
||||
},
|
||||
/* lh $r1,$gp16 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (GP16), 0 } },
|
||||
& ifmt_mva, { 0x1f400000 }
|
||||
},
|
||||
/* lhu $r1,$gp16 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (GP16), 0 } },
|
||||
& ifmt_mva, { 0x2f400000 }
|
||||
},
|
||||
/* lw $r1,$gp16 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (GP16), 0 } },
|
||||
& ifmt_mva, { 0x2b400000 }
|
||||
},
|
||||
/* sb $gp16,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (GP16), ',', OP (R1), 0 } },
|
||||
& ifmt_mva, { 0x33400000 }
|
||||
},
|
||||
/* sh $gp16,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (GP16), ',', OP (R1), 0 } },
|
||||
& ifmt_mva, { 0xf400000 }
|
||||
},
|
||||
/* sw $gp16,$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (GP16), ',', OP (R1), 0 } },
|
||||
& ifmt_mva, { 0x5b400000 }
|
||||
},
|
||||
/* lw $r1,(gp+$got16) */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', '(', 'g', 'p', '+', OP (GOT16), ')', 0 } },
|
||||
& ifmt_lwgotrel, { 0x2b400000 }
|
||||
},
|
||||
/* orhi $r1,$r0,$gotoffhi16 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (GOTOFFHI16), 0 } },
|
||||
& ifmt_orhigotoffi, { 0x78000000 }
|
||||
},
|
||||
/* addi $r1,$r0,$gotofflo16 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', OP (R0), ',', OP (GOTOFFLO16), 0 } },
|
||||
& ifmt_addgotoff, { 0x34000000 }
|
||||
},
|
||||
/* sw ($r0+$gotofflo16),$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', '(', OP (R0), '+', OP (GOTOFFLO16), ')', ',', OP (R1), 0 } },
|
||||
& ifmt_addgotoff, { 0x58000000 }
|
||||
},
|
||||
/* lw $r1,($r0+$gotofflo16) */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', '(', OP (R0), '+', OP (GOTOFFLO16), ')', 0 } },
|
||||
& ifmt_addgotoff, { 0x28000000 }
|
||||
},
|
||||
/* sh ($r0+$gotofflo16),$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', '(', OP (R0), '+', OP (GOTOFFLO16), ')', ',', OP (R1), 0 } },
|
||||
& ifmt_addgotoff, { 0xc000000 }
|
||||
},
|
||||
/* lh $r1,($r0+$gotofflo16) */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', '(', OP (R0), '+', OP (GOTOFFLO16), ')', 0 } },
|
||||
& ifmt_addgotoff, { 0x1c000000 }
|
||||
},
|
||||
/* lhu $r1,($r0+$gotofflo16) */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', '(', OP (R0), '+', OP (GOTOFFLO16), ')', 0 } },
|
||||
& ifmt_addgotoff, { 0x2c000000 }
|
||||
},
|
||||
/* sb ($r0+$gotofflo16),$r1 */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', '(', OP (R0), '+', OP (GOTOFFLO16), ')', ',', OP (R1), 0 } },
|
||||
& ifmt_addgotoff, { 0x30000000 }
|
||||
},
|
||||
/* lb $r1,($r0+$gotofflo16) */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', '(', OP (R0), '+', OP (GOTOFFLO16), ')', 0 } },
|
||||
& ifmt_addgotoff, { 0x10000000 }
|
||||
},
|
||||
/* lbu $r1,($r0+$gotofflo16) */
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ { MNEM, ' ', OP (R1), ',', '(', OP (R0), '+', OP (GOTOFFLO16), ')', 0 } },
|
||||
& ifmt_addgotoff, { 0x40000000 }
|
||||
},
|
||||
};
|
||||
|
||||
#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) & lm32_cgen_ifld_table[LM32_##f]
|
||||
#else
|
||||
#define F(f) & lm32_cgen_ifld_table[LM32_/**/f]
|
||||
#endif
|
||||
#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) LM32_OPERAND_##op
|
||||
#else
|
||||
#define OPERAND(op) LM32_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 lm32_cgen_macro_insn_table[] =
|
||||
{
|
||||
};
|
||||
|
||||
/* The macro instruction opcode table. */
|
||||
|
||||
static const CGEN_OPCODE lm32_cgen_macro_insn_opcode_table[] =
|
||||
{
|
||||
};
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
/* Set the recorded length of the insn in the CGEN_FIELDS struct. */
|
||||
|
||||
static void
|
||||
set_fields_bitsize (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
|
||||
lm32_cgen_init_opcode_table (CGEN_CPU_DESC cd)
|
||||
{
|
||||
int i;
|
||||
int num_macros = (sizeof (lm32_cgen_macro_insn_table) /
|
||||
sizeof (lm32_cgen_macro_insn_table[0]));
|
||||
const CGEN_IBASE *ib = & lm32_cgen_macro_insn_table[0];
|
||||
const CGEN_OPCODE *oc = & lm32_cgen_macro_insn_opcode_table[0];
|
||||
CGEN_INSN *insns = 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];
|
||||
lm32_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 = & lm32_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];
|
||||
lm32_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;
|
||||
}
|
105
opcodes/lm32-opc.h
Normal file
105
opcodes/lm32-opc.h
Normal file
@ -0,0 +1,105 @@
|
||||
/* Instruction opcode header for lm32.
|
||||
|
||||
THIS FILE IS MACHINE GENERATED WITH CGEN.
|
||||
|
||||
Copyright 1996-2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
|
||||
|
||||
This file 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 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
It 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.,
|
||||
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef LM32_OPC_H
|
||||
#define LM32_OPC_H
|
||||
|
||||
/* -- opc.h */
|
||||
|
||||
/* Allows reason codes to be output when assembler errors occur. */
|
||||
#define CGEN_VERBOSE_ASSEMBLER_ERRORS
|
||||
|
||||
#define CGEN_DIS_HASH_SIZE 64
|
||||
#define CGEN_DIS_HASH(buf,value) ((value >> 26) & 0x3f)
|
||||
|
||||
/* -- asm.c */
|
||||
/* Enum declaration for lm32 instruction types. */
|
||||
typedef enum cgen_insn_type {
|
||||
LM32_INSN_INVALID, LM32_INSN_ADD, LM32_INSN_ADDI, LM32_INSN_AND
|
||||
, LM32_INSN_ANDI, LM32_INSN_ANDHII, LM32_INSN_B, LM32_INSN_BI
|
||||
, LM32_INSN_BE, LM32_INSN_BG, LM32_INSN_BGE, LM32_INSN_BGEU
|
||||
, LM32_INSN_BGU, LM32_INSN_BNE, LM32_INSN_CALL, LM32_INSN_CALLI
|
||||
, LM32_INSN_CMPE, LM32_INSN_CMPEI, LM32_INSN_CMPG, LM32_INSN_CMPGI
|
||||
, LM32_INSN_CMPGE, LM32_INSN_CMPGEI, LM32_INSN_CMPGEU, LM32_INSN_CMPGEUI
|
||||
, LM32_INSN_CMPGU, LM32_INSN_CMPGUI, LM32_INSN_CMPNE, LM32_INSN_CMPNEI
|
||||
, LM32_INSN_DIVU, LM32_INSN_LB, LM32_INSN_LBU, LM32_INSN_LH
|
||||
, LM32_INSN_LHU, LM32_INSN_LW, LM32_INSN_MODU, LM32_INSN_MUL
|
||||
, LM32_INSN_MULI, LM32_INSN_NOR, LM32_INSN_NORI, LM32_INSN_OR
|
||||
, LM32_INSN_ORI, LM32_INSN_ORHII, LM32_INSN_RCSR, LM32_INSN_SB
|
||||
, LM32_INSN_SEXTB, LM32_INSN_SEXTH, LM32_INSN_SH, LM32_INSN_SL
|
||||
, LM32_INSN_SLI, LM32_INSN_SR, LM32_INSN_SRI, LM32_INSN_SRU
|
||||
, LM32_INSN_SRUI, LM32_INSN_SUB, LM32_INSN_SW, LM32_INSN_USER
|
||||
, LM32_INSN_WCSR, LM32_INSN_XOR, LM32_INSN_XORI, LM32_INSN_XNOR
|
||||
, LM32_INSN_XNORI, LM32_INSN_BREAK, LM32_INSN_SCALL, LM32_INSN_BRET
|
||||
, LM32_INSN_ERET, LM32_INSN_RET, LM32_INSN_MV, LM32_INSN_MVI
|
||||
, LM32_INSN_MVUI, LM32_INSN_MVHI, LM32_INSN_MVA, LM32_INSN_NOT
|
||||
, LM32_INSN_NOP, LM32_INSN_LBGPREL, LM32_INSN_LBUGPREL, LM32_INSN_LHGPREL
|
||||
, LM32_INSN_LHUGPREL, LM32_INSN_LWGPREL, LM32_INSN_SBGPREL, LM32_INSN_SHGPREL
|
||||
, LM32_INSN_SWGPREL, LM32_INSN_LWGOTREL, LM32_INSN_ORHIGOTOFFI, LM32_INSN_ADDGOTOFF
|
||||
, LM32_INSN_SWGOTOFF, LM32_INSN_LWGOTOFF, LM32_INSN_SHGOTOFF, LM32_INSN_LHGOTOFF
|
||||
, LM32_INSN_LHUGOTOFF, LM32_INSN_SBGOTOFF, LM32_INSN_LBGOTOFF, LM32_INSN_LBUGOTOFF
|
||||
} CGEN_INSN_TYPE;
|
||||
|
||||
/* Index of `invalid' insn place holder. */
|
||||
#define CGEN_INSN_INVALID LM32_INSN_INVALID
|
||||
|
||||
/* Total number of insns in table. */
|
||||
#define MAX_INSNS ((int) LM32_INSN_LBUGOTOFF + 1)
|
||||
|
||||
/* This struct records data prior to insertion or after extraction. */
|
||||
struct cgen_fields
|
||||
{
|
||||
int length;
|
||||
long f_nil;
|
||||
long f_anyof;
|
||||
long f_opcode;
|
||||
long f_r0;
|
||||
long f_r1;
|
||||
long f_r2;
|
||||
long f_resv0;
|
||||
long f_shift;
|
||||
long f_imm;
|
||||
long f_uimm;
|
||||
long f_csr;
|
||||
long f_user;
|
||||
long f_exception;
|
||||
long f_branch;
|
||||
long f_call;
|
||||
};
|
||||
|
||||
#define CGEN_INIT_PARSE(od) \
|
||||
{\
|
||||
}
|
||||
#define CGEN_INIT_INSERT(od) \
|
||||
{\
|
||||
}
|
||||
#define CGEN_INIT_EXTRACT(od) \
|
||||
{\
|
||||
}
|
||||
#define CGEN_INIT_PRINT(od) \
|
||||
{\
|
||||
}
|
||||
|
||||
|
||||
#endif /* LM32_OPC_H */
|
473
opcodes/lm32-opinst.c
Normal file
473
opcodes/lm32-opinst.c
Normal file
@ -0,0 +1,473 @@
|
||||
/* Semantic operand instances for lm32.
|
||||
|
||||
THIS FILE IS MACHINE GENERATED WITH CGEN.
|
||||
|
||||
Copyright 1996-2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
|
||||
|
||||
This file 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 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
It 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.,
|
||||
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "sysdep.h"
|
||||
#include "ansidecl.h"
|
||||
#include "bfd.h"
|
||||
#include "symcat.h"
|
||||
#include "lm32-desc.h"
|
||||
#include "lm32-opc.h"
|
||||
|
||||
/* Operand references. */
|
||||
|
||||
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
|
||||
#define OP_ENT(op) LM32_OPERAND_##op
|
||||
#else
|
||||
#define OP_ENT(op) LM32_OPERAND_/**/op
|
||||
#endif
|
||||
#define INPUT CGEN_OPINST_INPUT
|
||||
#define OUTPUT CGEN_OPINST_OUTPUT
|
||||
#define END CGEN_OPINST_END
|
||||
#define COND_REF CGEN_OPINST_COND_REF
|
||||
|
||||
static const CGEN_OPINST sfmt_empty_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_add_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ OUTPUT, "r2", HW_H_GR, CGEN_MODE_SI, OP_ENT (R2), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_addi_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "imm", HW_H_SINT, CGEN_MODE_INT, OP_ENT (IMM), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_andi_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "uimm", HW_H_UINT, CGEN_MODE_UINT, OP_ENT (UIMM), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_andhii_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "hi16", HW_H_UINT, CGEN_MODE_SI, OP_ENT (HI16), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_b_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "f_r0", HW_H_UINT, CGEN_MODE_UINT, 0, 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_bi_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "call", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (CALL), 0, 0 },
|
||||
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_be_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "branch", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (BRANCH), 0, COND_REF },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, COND_REF },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_call_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "h_gr_SI_29", HW_H_GR, CGEN_MODE_SI, 0, 29, 0 },
|
||||
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_calli_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "call", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (CALL), 0, 0 },
|
||||
{ INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
|
||||
{ OUTPUT, "h_gr_SI_29", HW_H_GR, CGEN_MODE_SI, 0, 29, 0 },
|
||||
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_divu_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "f_r0", HW_H_UINT, CGEN_MODE_UINT, 0, 0, 0 },
|
||||
{ INPUT, "f_r1", HW_H_UINT, CGEN_MODE_UINT, 0, 0, 0 },
|
||||
{ INPUT, "f_r2", HW_H_UINT, CGEN_MODE_UINT, 0, 0, 0 },
|
||||
{ INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
|
||||
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_lb_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "h_memory_QI_add__DFLT_r0_ext__SI_trunc__HI_imm", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
|
||||
{ INPUT, "imm", HW_H_SINT, CGEN_MODE_INT, OP_ENT (IMM), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_lh_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "h_memory_HI_add__DFLT_r0_ext__SI_trunc__HI_imm", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
|
||||
{ INPUT, "imm", HW_H_SINT, CGEN_MODE_INT, OP_ENT (IMM), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_lw_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "h_memory_SI_add__DFLT_r0_ext__SI_trunc__HI_imm", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
|
||||
{ INPUT, "imm", HW_H_SINT, CGEN_MODE_INT, OP_ENT (IMM), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_ori_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "lo16", HW_H_UINT, CGEN_MODE_UINT, OP_ENT (LO16), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_rcsr_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "csr", HW_H_CSR, CGEN_MODE_SI, OP_ENT (CSR), 0, 0 },
|
||||
{ OUTPUT, "r2", HW_H_GR, CGEN_MODE_SI, OP_ENT (R2), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_sb_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "imm", HW_H_SINT, CGEN_MODE_INT, OP_ENT (IMM), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ OUTPUT, "h_memory_QI_add__DFLT_r0_ext__SI_trunc__HI_imm", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_sextb_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r2", HW_H_GR, CGEN_MODE_SI, OP_ENT (R2), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_sh_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "imm", HW_H_SINT, CGEN_MODE_INT, OP_ENT (IMM), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ OUTPUT, "h_memory_HI_add__DFLT_r0_ext__SI_trunc__HI_imm", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_sl_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_INT, OP_ENT (R1), 0, 0 },
|
||||
{ OUTPUT, "r2", HW_H_GR, CGEN_MODE_SI, OP_ENT (R2), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_sw_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "imm", HW_H_SINT, CGEN_MODE_INT, OP_ENT (IMM), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ OUTPUT, "h_memory_SI_add__DFLT_r0_ext__SI_trunc__HI_imm", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_user_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ INPUT, "user", HW_H_UINT, CGEN_MODE_UINT, OP_ENT (USER), 0, 0 },
|
||||
{ OUTPUT, "r2", HW_H_GR, CGEN_MODE_SI, OP_ENT (R2), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_wcsr_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "f_csr", HW_H_UINT, CGEN_MODE_UINT, 0, 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_break_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
|
||||
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_bret_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_mvui_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "lo16", HW_H_UINT, CGEN_MODE_UINT, OP_ENT (LO16), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_mva_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gp16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GP16), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_nop_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_lbgprel_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gp16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GP16), 0, 0 },
|
||||
{ INPUT, "h_memory_QI_add__DFLT_r0_ext__SI_trunc__HI_gp16", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_lhgprel_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gp16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GP16), 0, 0 },
|
||||
{ INPUT, "h_memory_HI_add__DFLT_r0_ext__SI_trunc__HI_gp16", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_lwgprel_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gp16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GP16), 0, 0 },
|
||||
{ INPUT, "h_memory_SI_add__DFLT_r0_ext__SI_trunc__HI_gp16", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_sbgprel_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gp16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GP16), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ OUTPUT, "h_memory_QI_add__DFLT_r0_ext__SI_trunc__HI_gp16", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_shgprel_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gp16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GP16), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ OUTPUT, "h_memory_HI_add__DFLT_r0_ext__SI_trunc__HI_gp16", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_swgprel_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gp16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GP16), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ OUTPUT, "h_memory_SI_add__DFLT_r0_ext__SI_trunc__HI_gp16", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_lwgotrel_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "got16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GOT16), 0, 0 },
|
||||
{ INPUT, "h_memory_SI_add__DFLT_r0_ext__SI_trunc__HI_got16", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_orhigotoffi_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gotoffhi16", HW_H_SINT, CGEN_MODE_SI, OP_ENT (GOTOFFHI16), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_addgotoff_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gotofflo16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GOTOFFLO16), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_swgotoff_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gotofflo16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GOTOFFLO16), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ OUTPUT, "h_memory_SI_add__DFLT_r0_ext__SI_trunc__HI_gotofflo16", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_lwgotoff_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gotofflo16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GOTOFFLO16), 0, 0 },
|
||||
{ INPUT, "h_memory_SI_add__DFLT_r0_ext__SI_trunc__HI_gotofflo16", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_shgotoff_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gotofflo16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GOTOFFLO16), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ OUTPUT, "h_memory_HI_add__DFLT_r0_ext__SI_trunc__HI_gotofflo16", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_lhgotoff_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gotofflo16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GOTOFFLO16), 0, 0 },
|
||||
{ INPUT, "h_memory_HI_add__DFLT_r0_ext__SI_trunc__HI_gotofflo16", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_sbgotoff_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gotofflo16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GOTOFFLO16), 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ INPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ OUTPUT, "h_memory_QI_add__DFLT_r0_ext__SI_trunc__HI_gotofflo16", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
static const CGEN_OPINST sfmt_lbgotoff_ops[] ATTRIBUTE_UNUSED = {
|
||||
{ INPUT, "gotofflo16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (GOTOFFLO16), 0, 0 },
|
||||
{ INPUT, "h_memory_QI_add__DFLT_r0_ext__SI_trunc__HI_gotofflo16", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
|
||||
{ INPUT, "r0", HW_H_GR, CGEN_MODE_SI, OP_ENT (R0), 0, 0 },
|
||||
{ OUTPUT, "r1", HW_H_GR, CGEN_MODE_SI, OP_ENT (R1), 0, 0 },
|
||||
{ END, (const char *)0, (enum cgen_hw_type)0, (enum cgen_mode)0, (enum cgen_operand_type)0, 0, 0 }
|
||||
};
|
||||
|
||||
#undef OP_ENT
|
||||
#undef INPUT
|
||||
#undef OUTPUT
|
||||
#undef END
|
||||
#undef COND_REF
|
||||
|
||||
/* Operand instance lookup table. */
|
||||
|
||||
static const CGEN_OPINST *lm32_cgen_opinst_table[MAX_INSNS] = {
|
||||
0,
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_addi_ops[0],
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_andi_ops[0],
|
||||
& sfmt_andhii_ops[0],
|
||||
& sfmt_b_ops[0],
|
||||
& sfmt_bi_ops[0],
|
||||
& sfmt_be_ops[0],
|
||||
& sfmt_be_ops[0],
|
||||
& sfmt_be_ops[0],
|
||||
& sfmt_be_ops[0],
|
||||
& sfmt_be_ops[0],
|
||||
& sfmt_be_ops[0],
|
||||
& sfmt_call_ops[0],
|
||||
& sfmt_calli_ops[0],
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_addi_ops[0],
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_addi_ops[0],
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_addi_ops[0],
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_andi_ops[0],
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_andi_ops[0],
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_addi_ops[0],
|
||||
& sfmt_divu_ops[0],
|
||||
& sfmt_lb_ops[0],
|
||||
& sfmt_lb_ops[0],
|
||||
& sfmt_lh_ops[0],
|
||||
& sfmt_lh_ops[0],
|
||||
& sfmt_lw_ops[0],
|
||||
& sfmt_divu_ops[0],
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_addi_ops[0],
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_andi_ops[0],
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_ori_ops[0],
|
||||
& sfmt_andhii_ops[0],
|
||||
& sfmt_rcsr_ops[0],
|
||||
& sfmt_sb_ops[0],
|
||||
& sfmt_sextb_ops[0],
|
||||
& sfmt_sextb_ops[0],
|
||||
& sfmt_sh_ops[0],
|
||||
& sfmt_sl_ops[0],
|
||||
& sfmt_addi_ops[0],
|
||||
& sfmt_sl_ops[0],
|
||||
& sfmt_addi_ops[0],
|
||||
& sfmt_sl_ops[0],
|
||||
& sfmt_addi_ops[0],
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_sw_ops[0],
|
||||
& sfmt_user_ops[0],
|
||||
& sfmt_wcsr_ops[0],
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_andi_ops[0],
|
||||
& sfmt_add_ops[0],
|
||||
& sfmt_andi_ops[0],
|
||||
& sfmt_break_ops[0],
|
||||
& sfmt_break_ops[0],
|
||||
& sfmt_bret_ops[0],
|
||||
& sfmt_bret_ops[0],
|
||||
& sfmt_bret_ops[0],
|
||||
& sfmt_sextb_ops[0],
|
||||
& sfmt_addi_ops[0],
|
||||
& sfmt_mvui_ops[0],
|
||||
& sfmt_andhii_ops[0],
|
||||
& sfmt_mva_ops[0],
|
||||
& sfmt_sextb_ops[0],
|
||||
& sfmt_nop_ops[0],
|
||||
& sfmt_lbgprel_ops[0],
|
||||
& sfmt_lbgprel_ops[0],
|
||||
& sfmt_lhgprel_ops[0],
|
||||
& sfmt_lhgprel_ops[0],
|
||||
& sfmt_lwgprel_ops[0],
|
||||
& sfmt_sbgprel_ops[0],
|
||||
& sfmt_shgprel_ops[0],
|
||||
& sfmt_swgprel_ops[0],
|
||||
& sfmt_lwgotrel_ops[0],
|
||||
& sfmt_orhigotoffi_ops[0],
|
||||
& sfmt_addgotoff_ops[0],
|
||||
& sfmt_swgotoff_ops[0],
|
||||
& sfmt_lwgotoff_ops[0],
|
||||
& sfmt_shgotoff_ops[0],
|
||||
& sfmt_lhgotoff_ops[0],
|
||||
& sfmt_lhgotoff_ops[0],
|
||||
& sfmt_sbgotoff_ops[0],
|
||||
& sfmt_lbgotoff_ops[0],
|
||||
& sfmt_lbgotoff_ops[0],
|
||||
};
|
||||
|
||||
/* Function to call before using the operand instance table. */
|
||||
|
||||
void
|
||||
lm32_cgen_init_opinst_table (cd)
|
||||
CGEN_CPU_DESC cd;
|
||||
{
|
||||
int i;
|
||||
const CGEN_OPINST **oi = & lm32_cgen_opinst_table[0];
|
||||
CGEN_INSN *insns = (CGEN_INSN *) cd->insn_table.init_entries;
|
||||
for (i = 0; i < MAX_INSNS; ++i)
|
||||
insns[i].opinst = oi[i];
|
||||
}
|
Loading…
Reference in New Issue
Block a user