kumquat-buildroot/toolchain/gdb/6.6/700-nios2-6.6.patch

7979 lines
254 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 435b30b..488c4ab 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -92,6 +92,7 @@ ALL_MACHINES = \
cpu-maxq.lo \
cpu-mcore.lo \
cpu-mips.lo \
+ cpu-nios2.lo \
cpu-mmix.lo \
cpu-mt.lo \
cpu-msp430.lo \
@@ -156,6 +157,7 @@ ALL_MACHINES_CFILES = \
cpu-maxq.c \
cpu-mcore.c \
cpu-mips.c \
+ cpu-nios2.c \
cpu-mmix.c \
cpu-mt.c \
cpu-msp430.c \
@@ -270,6 +272,7 @@ BFD32_BACKENDS = \
elf32-mips.lo \
elf32-mt.lo \
elf32-msp430.lo \
+ elf32-nios2.lo \
elf32-openrisc.lo \
elf32-or32.lo \
elf32-pj.lo \
@@ -446,6 +449,7 @@ BFD32_BACKENDS_CFILES = \
elf32-mips.c \
elf32-mt.c \
elf32-msp430.c \
+ elf32-nios2.c \
elf32-openrisc.c \
elf32-or32.c \
elf32-pj.c \
@@ -1065,6 +1069,7 @@ cpu-m10300.lo: cpu-m10300.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-maxq.lo: cpu-maxq.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-mcore.lo: cpu-mcore.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-mips.lo: cpu-mips.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
+cpu-nios2.lo: cpu-nios2.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-mmix.lo: cpu-mmix.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-mt.lo: cpu-mt.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-msp430.lo: cpu-msp430.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
@@ -1428,6 +1433,10 @@ elf32-msp430.lo: elf32-msp430.c $(INCDIR)/filenames.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
$(INCDIR)/bfdlink.h $(INCDIR)/elf/msp430.h $(INCDIR)/elf/reloc-macros.h \
elf32-target.h
+elf32-nios2.lo: elf32-nios2.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
+ genlink.h elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/elf/nios2.h \
+ $(INCDIR)/elf/reloc-macros.h elf32-target.h
elf32-openrisc.lo: elf32-openrisc.c $(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
$(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 5bde689..5e57321 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -327,6 +327,7 @@ ALL_MACHINES = \
cpu-mt.lo \
cpu-msp430.lo \
cpu-or32.lo \
+ cpu-nios2.lo \
cpu-ns32k.lo \
cpu-openrisc.lo \
cpu-pdp11.lo \
@@ -391,6 +392,7 @@ ALL_MACHINES_CFILES = \
cpu-mt.c \
cpu-msp430.c \
cpu-or32.c \
+ cpu-nios2.c \
cpu-ns32k.c \
cpu-openrisc.c \
cpu-pdp11.c \
@@ -502,6 +504,7 @@ BFD32_BACKENDS = \
elf32-mips.lo \
elf32-mt.lo \
elf32-msp430.lo \
+ elf32-nios2.lo \
elf32-openrisc.lo \
elf32-or32.lo \
elf32-pj.lo \
@@ -678,6 +681,7 @@ BFD32_BACKENDS_CFILES = \
elf32-mips.c \
elf32-mt.c \
elf32-msp430.c \
+ elf32-nios2.c \
elf32-openrisc.c \
elf32-or32.c \
elf32-pj.c \
@@ -1626,6 +1630,7 @@ cpu-m10300.lo: cpu-m10300.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-maxq.lo: cpu-maxq.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-mcore.lo: cpu-mcore.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-mips.lo: cpu-mips.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
+cpu-nios2.lo: cpu-nios2.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-mmix.lo: cpu-mmix.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-mt.lo: cpu-mt.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
cpu-msp430.lo: cpu-msp430.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
@@ -1989,6 +1994,10 @@ elf32-msp430.lo: elf32-msp430.c $(INCDIR)/filenames.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
$(INCDIR)/bfdlink.h $(INCDIR)/elf/msp430.h $(INCDIR)/elf/reloc-macros.h \
elf32-target.h
+elf32-nios2.lo: elf32-nios2.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
+ genlink.h elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/elf/nios2.h \
+ $(INCDIR)/elf/reloc-macros.h elf32-target.h
elf32-openrisc.lo: elf32-openrisc.c $(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
$(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
diff --git a/bfd/archures.c b/bfd/archures.c
index 5029cb0..ece60b4 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -381,6 +381,8 @@ DESCRIPTION
. bfd_arch_maxq, {* Dallas MAXQ 10/20 *}
.#define bfd_mach_maxq10 10
.#define bfd_mach_maxq20 20
+. bfd_arch_nios2,
+.#define bfd_mach_nios2 1
. bfd_arch_z80,
.#define bfd_mach_z80strict 1 {* No undocumented opcodes. *}
.#define bfd_mach_z80 3 {* With ixl, ixh, iyl, and iyh. *}
@@ -462,6 +464,7 @@ extern const bfd_arch_info_type bfd_mn10300_arch;
extern const bfd_arch_info_type bfd_msp430_arch;
extern const bfd_arch_info_type bfd_mt_arch;
extern const bfd_arch_info_type bfd_ns32k_arch;
+extern const bfd_arch_info_type bfd_nios2_arch;
extern const bfd_arch_info_type bfd_openrisc_arch;
extern const bfd_arch_info_type bfd_or32_arch;
extern const bfd_arch_info_type bfd_pdp11_arch;
@@ -530,6 +533,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] =
&bfd_mn10300_arch,
&bfd_mt_arch,
&bfd_msp430_arch,
+ &bfd_nios2_arch,
&bfd_ns32k_arch,
&bfd_openrisc_arch,
&bfd_or32_arch,
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 8f2af8b..f5c51d6 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2010,6 +2010,8 @@ enum bfd_architecture
bfd_arch_maxq, /* Dallas MAXQ 10/20 */
#define bfd_mach_maxq10 10
#define bfd_mach_maxq20 20
+ bfd_arch_nios2,
+#define bfd_mach_nios2 1
bfd_arch_z80,
#define bfd_mach_z80strict 1 /* No undocumented opcodes. */
#define bfd_mach_z80 3 /* With ixl, ixh, iyl, and iyh. */
@@ -4271,6 +4273,23 @@ internally by the linker after analysis of a
BFD_RELOC_XTENSA_ASM_EXPAND. */
BFD_RELOC_XTENSA_ASM_SIMPLIFY,
+/* Relocations used by the Altera New Jersey core */
+ BFD_RELOC_NIOS2_S16,
+ BFD_RELOC_NIOS2_U16,
+ BFD_RELOC_NIOS2_CALL26,
+ BFD_RELOC_NIOS2_IMM5,
+ BFD_RELOC_NIOS2_CACHE_OPX,
+ BFD_RELOC_NIOS2_IMM6,
+ BFD_RELOC_NIOS2_IMM8,
+ BFD_RELOC_NIOS2_HI16,
+ BFD_RELOC_NIOS2_LO16,
+ BFD_RELOC_NIOS2_HIADJ16,
+ BFD_RELOC_NIOS2_GPREL,
+ BFD_RELOC_NIOS2_UJMP,
+ BFD_RELOC_NIOS2_CJMP,
+ BFD_RELOC_NIOS2_CALLR,
+ BFD_RELOC_NIOS2_ALIGN,
+
/* 8 bit signed offset in (ix+d) or (iy+d). */
BFD_RELOC_Z80_DISP8,
diff --git a/bfd/config.bfd b/bfd/config.bfd
old mode 100755
new mode 100644
index 9b81db7..fa86103
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -88,6 +88,7 @@ m68*) targ_archs=bfd_m68k_arch ;;
m88*) targ_archs=bfd_m88k_arch ;;
maxq*) targ_archs=bfd_maxq_arch ;;
mips*) targ_archs=bfd_mips_arch ;;
+nios2*) targ_archs=bfd_nios2_arch ;;
or32*) targ_archs=bfd_or32_arch ;;
pdp11*) targ_archs=bfd_pdp11_arch ;;
pj*) targ_archs="bfd_pj_arch bfd_i386_arch";;
@@ -985,6 +986,21 @@ case "${targ}" in
targ_underscore=yes
;;
+ nios2eb-*-*)
+ targ_defvec=bfd_elf32_bignios2_vec
+ targ_selvecs=bfd_elf32_littlenios2_vec
+ ;;
+
+ nios2el-*-*)
+ targ_defvec=bfd_elf32_littlenios2_vec
+ targ_selvecs=bfd_elf32_bignios2_vec
+ ;;
+
+ nios2-*-*)
+ targ_defvec=bfd_elf32_littlenios2_vec
+ targ_selvecs=bfd_elf32_bignios2_vec
+ ;;
+
openrisc-*-elf)
targ_defvec=bfd_elf32_openrisc_vec
;;
diff --git a/bfd/configure b/bfd/configure
index bc138ff..a64fef5 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -10846,6 +10846,8 @@ do
bfd_elf32_littlemips_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
bfd_elf32_littlemips_vxworks_vec)
tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ bfd_elf32_littlenios2_vec) tb="$tb elf32-nios2.lo elf32.lo $elf" ;;
+ bfd_elf32_bignios2_vec) tb="$tb elf32-nios2.lo elf32.lo $elf" ;;
bfd_elf32_m32c_vec) tb="$tb elf32-m32c.lo elf32.lo $elf" ;;
bfd_elf32_m32r_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
bfd_elf32_m32rle_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
diff --git a/bfd/configure.in b/bfd/configure.in
index fa0d50f..eb1e5f6 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -655,6 +655,8 @@ do
bfd_elf32_nlittlemips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf32_ntradbigmips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf32_ntradlittlemips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ bfd_elf32_littlenios2_vec) tb="$tb elf32-nios2.lo elf32.lo $elf" ;;
+ bfd_elf32_bignios2_vec) tb="$tb elf32-nios2.lo elf32.lo $elf" ;;
bfd_elf32_openrisc_vec) tb="$tb elf32-openrisc.lo elf32.lo $elf" ;;
bfd_elf32_or32_big_vec) tb="$tb elf32-or32.lo elf32.lo $elf" ;;
bfd_elf32_pj_vec) tb="$tb elf32-pj.lo elf32.lo $elf";;
diff --git a/bfd/cpu-nios2.c b/bfd/cpu-nios2.c
new file mode 100644
index 0000000..c8f39c9
--- /dev/null
+++ b/bfd/cpu-nios2.c
@@ -0,0 +1,70 @@
+/* bfd back-end for Altera Nios II support
+
+ Copyright (C) 2003
+ by Nigel Gray (ngray@altera.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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+static const bfd_arch_info_type *nios2_compatible
+ (const bfd_arch_info_type *, const bfd_arch_info_type *);
+
+/* The default routine tests bits_per_word, which is wrong on mips as
+ mips word size doesn't correlate with reloc size. */
+
+static const bfd_arch_info_type *
+nios2_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
+{
+ if (a->arch != b->arch)
+ return NULL;
+
+ /* Machine compatibility is checked in
+ _bfd_mips_elf_merge_private_bfd_data. */
+
+ return a;
+}
+
+#define N(BITS_WORD, BITS_ADDR, NUMBER, PRINT, DEFAULT, NEXT) \
+ { \
+ BITS_WORD, /* bits in a word */ \
+ BITS_ADDR, /* bits in an address */ \
+ 8, /* 8 bits in a byte */ \
+ bfd_arch_nios2, \
+ NUMBER, \
+ "nios2", \
+ PRINT, \
+ 3, \
+ DEFAULT, \
+ nios2_compatible, \
+ bfd_default_scan, \
+ NEXT, \
+ }
+
+#define NN(index) (&arch_info_struct[(index) + 1])
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N (32, 32, bfd_mach_nios2, "nios2", FALSE, 0),
+};
+
+/* There is only one architecture - but we give the default a machine number of 0
+ so the linker can distinguish it */
+const bfd_arch_info_type bfd_nios2_arch =
+N (32, 32, 0, "nios2", TRUE, &arch_info_struct[0]);
diff --git a/bfd/elf32-nios2.c b/bfd/elf32-nios2.c
new file mode 100644
index 0000000..f9ba1a0
--- /dev/null
+++ b/bfd/elf32-nios2.c
@@ -0,0 +1,2193 @@
+/* New Jersey-specific support for 32-bit ELF
+
+ Copyright (C) 2003
+ by Nigel Gray (ngray@altera.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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file handles Altera New Jersey ELF targets */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "genlink.h"
+#include "elf-bfd.h"
+#include "elf/nios2.h"
+#include "opcode/nios2.h"
+
+/* use RELA relocations*/
+#ifndef USE_RELA
+#define USE_RELA
+#endif
+
+#ifdef USE_REL
+#undef USE_REL
+#endif
+
+/* Function prototypes */
+
+static reloc_howto_type *nios2_elf32_bfd_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+
+static bfd_boolean nios2_elf32_relax_section
+ (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
+
+static bfd_boolean nios2_elf32_relax_delete_bytes
+ (bfd *, asection *, bfd_vma, int);
+
+static reloc_howto_type *nios2_elf32_rtype_to_howto
+ (unsigned int r_type, bfd_boolean rela_p);
+
+static void nios2_elf32_info_to_howto
+ (bfd * abfd, arelent * cache_ptr, Elf_Internal_Rela * dst);
+
+static bfd_boolean nios2_elf32_relocate_section
+ (bfd * output_bfd, struct bfd_link_info * info, bfd * input_bfd,
+ asection * input_section, bfd_byte * contents,
+ Elf_Internal_Rela * relocs, Elf_Internal_Sym * local_syms,
+ asection ** local_sections);
+
+static reloc_howto_type *lookup_howto (unsigned int rtype);
+
+static bfd_reloc_status_type nios2_elf_final_gp
+ (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *,
+ struct bfd_link_info *);
+
+static bfd_boolean nios2_elf_assign_gp
+ (bfd *, bfd_vma *, struct bfd_link_info *);
+
+static bfd_reloc_status_type nios2_elf32_ignore_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+static bfd_reloc_status_type nios2_elf32_hi16_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+static bfd_reloc_status_type nios2_elf32_lo16_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+static bfd_reloc_status_type nios2_elf32_hiadj16_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+static bfd_reloc_status_type nios2_elf32_pcrel16_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+static bfd_reloc_status_type nios2_elf32_call26_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+static bfd_reloc_status_type nios2_elf32_gprel_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+static bfd_reloc_status_type nios2_elf32_ujmp_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+static bfd_reloc_status_type nios2_elf32_cjmp_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+static bfd_reloc_status_type nios2_elf32_callr_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+static bfd_reloc_status_type nios2_elf32_do_hi16_relocate
+ (bfd *, reloc_howto_type *, asection *,
+ bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
+
+static bfd_reloc_status_type nios2_elf32_do_lo16_relocate
+ (bfd *, reloc_howto_type *, asection *,
+ bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
+
+static bfd_reloc_status_type nios2_elf32_do_hiadj16_relocate
+ (bfd *, reloc_howto_type *, asection *,
+ bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
+
+static bfd_reloc_status_type nios2_elf32_do_pcrel16_relocate
+ (bfd *, reloc_howto_type *, asection *,
+ bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
+
+static bfd_reloc_status_type nios2_elf32_do_call26_relocate
+ (bfd *, reloc_howto_type *, asection *,
+ bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
+
+static bfd_reloc_status_type nios2_elf32_do_gprel_relocate
+ (bfd *, reloc_howto_type *, asection *,
+ bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
+
+static bfd_reloc_status_type nios2_elf32_do_ujmp_relocate
+ (bfd *, reloc_howto_type *, asection *,
+ bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
+
+static bfd_reloc_status_type nios2_elf32_do_cjmp_relocate
+ (bfd *, reloc_howto_type *, asection *,
+ bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
+
+static bfd_reloc_status_type nios2_elf32_do_callr_relocate
+ (bfd *, reloc_howto_type *, asection *,
+ bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
+
+
+static void nios2_elf32_post_process_headers
+ (bfd *, struct bfd_link_info *);
+
+static bfd_boolean nios2_elf32_section_from_shdr
+ (bfd *, Elf_Internal_Shdr *, const char *name, int shindex);
+
+static bfd_boolean nios2_elf32_section_flags
+ (flagword *, const Elf_Internal_Shdr *);
+
+static bfd_boolean nios2_elf32_fake_sections
+ (bfd *, Elf_Internal_Shdr *, asection *);
+
+
+
+static bfd_boolean nios2_elf32_check_relocs
+ (bfd *, struct bfd_link_info *, asection *,
+ const Elf_Internal_Rela *);
+
+static asection *nios2_elf32_gc_mark_hook (asection * sec,
+ struct bfd_link_info *
+ info,
+ Elf_Internal_Rela * rel,
+ struct elf_link_hash_entry
+ * h,
+ Elf_Internal_Sym * sym);
+
+
+/* target vector */
+extern const bfd_target bfd_elf32_littlenios2_vec;
+extern const bfd_target bfd_elf32_bignios2_vec;
+
+/* The relocation table used for SHT_REL sections. */
+
+static reloc_howto_type elf_nios2_howto_table_rel[] = {
+ /* No relocation. */
+ HOWTO (R_NIOS2_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NIOS2_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16-bit signed immediate relocation */
+ HOWTO (R_NIOS2_S16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_signed, /* complain on overflow */
+ bfd_elf_generic_reloc, /* special function */
+ "R_NIOS2_S16", /* name */
+ FALSE, /* partial_inplace */
+ 0x003fffc0, /* src_mask */
+ 0x003fffc0, /* dest_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16-bit unsigned immediate relocation */
+ HOWTO (R_NIOS2_U16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_unsigned, /* complain on overflow */
+ bfd_elf_generic_reloc, /* special function */
+ "R_NIOS2_U16", /* name */
+ FALSE, /* partial_inplace */
+ 0x003fffc0, /* src_mask */
+ 0x003fffc0, /* dest_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_NIOS2_PCREL16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_signed, /* complain on overflow */
+ nios2_elf32_pcrel16_relocate, /* special function */
+ "R_NIOS2_PCREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0x003fffc0, /* src_mask */
+ 0x003fffc0, /* dest_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_NIOS2_CALL26, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ FALSE, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_dont, /* complain on overflow */
+ nios2_elf32_call26_relocate, /* special function */
+ "R_NIOS2_CALL26", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffc0, /* src_mask */
+ 0xffffffc0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_NIOS2_IMM5,
+ 0,
+ 2,
+ 5,
+ FALSE,
+ 6,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_IMM5",
+ FALSE,
+ 0x000007c0,
+ 0x000007c0,
+ FALSE),
+
+ HOWTO (R_NIOS2_CACHE_OPX,
+ 0,
+ 2,
+ 5,
+ FALSE,
+ 22,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_CACHE_OPX",
+ FALSE,
+ 0x07c00000,
+ 0x07c00000,
+ FALSE),
+
+ HOWTO (R_NIOS2_IMM6,
+ 0,
+ 2,
+ 6,
+ FALSE,
+ 6,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_IMM6",
+ FALSE,
+ 0x00000fc0,
+ 0x00000fc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_IMM8,
+ 0,
+ 2,
+ 8,
+ FALSE,
+ 6,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_IMM8",
+ FALSE,
+ 0x00003fc0,
+ 0x00003fc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_HI16,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_hi16_relocate,
+ "R_NIOS2_HI16",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_LO16,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_lo16_relocate,
+ "R_NIOS2_LO16",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_HIADJ16,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_hiadj16_relocate,
+ "R_NIOS2_HIADJ16",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_BFD_RELOC_32,
+ 0,
+ 2, /* long */
+ 32,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_BFD_RELOC32",
+ FALSE,
+ 0xffffffff,
+ 0xffffffff,
+ FALSE),
+
+ HOWTO (R_NIOS2_BFD_RELOC_16,
+ 0,
+ 1, /* short */
+ 16,
+ FALSE,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_BFD_RELOC16",
+ FALSE,
+ 0x0000ffff,
+ 0x0000ffff,
+ FALSE),
+
+ HOWTO (R_NIOS2_BFD_RELOC_8,
+ 0,
+ 0, /* byte */
+ 8,
+ FALSE,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_BFD_RELOC8",
+ FALSE,
+ 0x000000ff,
+ 0x000000ff,
+ FALSE),
+
+ HOWTO (R_NIOS2_GPREL,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_gprel_relocate,
+ "R_NIOS2_GPREL",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_GNU_VTINHERIT,
+ 0,
+ 2, /* short */
+ 0,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ NULL,
+ "R_NIOS2_GNU_VTINHERIT",
+ FALSE,
+ 0,
+ 0,
+ FALSE),
+
+ HOWTO (R_NIOS2_GNU_VTENTRY,
+ 0,
+ 2, /* byte */
+ 0,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ _bfd_elf_rel_vtable_reloc_fn,
+ "R_NIOS2_GNU_VTENTRY",
+ FALSE,
+ 0,
+ 0,
+ FALSE),
+
+ HOWTO (R_NIOS2_UJMP,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_ujmp_relocate,
+ "R_NIOS2_UJMP",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_CJMP,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_cjmp_relocate,
+ "R_NIOS2_CJMP",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_CALLR,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_callr_relocate,
+ "R_NIOS2_CALLR",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_ALIGN,
+ 0,
+ 2,
+ 0,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ nios2_elf32_ignore_reloc,
+ "R_NIOS2_ALIGN",
+ FALSE,
+ 0,
+ 0,
+ TRUE),
+
+/* add other relocations here */
+};
+
+static unsigned char elf_code_to_howto_index[R_NIOS2_ILLEGAL + 1];
+
+static reloc_howto_type *
+lookup_howto (unsigned int rtype)
+{
+ static int initialized = 0;
+ int i;
+ int howto_tbl_size = (int) (sizeof (elf_nios2_howto_table_rel)
+ / sizeof (elf_nios2_howto_table_rel[0]));
+
+ if (!initialized)
+ {
+ initialized = 1;
+ memset (elf_code_to_howto_index, 0xff,
+ sizeof (elf_code_to_howto_index));
+ for (i = 0; i < howto_tbl_size; i++)
+ elf_code_to_howto_index[elf_nios2_howto_table_rel[i].type] = i;
+ }
+
+ BFD_ASSERT (rtype <= R_NIOS2_ILLEGAL);
+ i = elf_code_to_howto_index[rtype];
+ if (i >= howto_tbl_size)
+ return 0;
+ return elf_nios2_howto_table_rel + i;
+}
+
+/*
+ map for converting BFD reloc types to New Jersey
+ reloc types
+ */
+struct elf_reloc_map
+{
+ bfd_reloc_code_real_type bfd_val;
+ enum elf_nios2_reloc_type elf_val;
+};
+
+static const struct elf_reloc_map nios2_reloc_map[] = {
+ {BFD_RELOC_NIOS2_S16, R_NIOS2_S16},
+ {BFD_RELOC_NIOS2_U16, R_NIOS2_U16},
+ {BFD_RELOC_16_PCREL, R_NIOS2_PCREL16},
+ {BFD_RELOC_NIOS2_CALL26, R_NIOS2_CALL26},
+ {BFD_RELOC_NIOS2_IMM5, R_NIOS2_IMM5},
+ {BFD_RELOC_NIOS2_CACHE_OPX, R_NIOS2_CACHE_OPX},
+ {BFD_RELOC_NIOS2_IMM6, R_NIOS2_IMM6},
+ {BFD_RELOC_NIOS2_IMM8, R_NIOS2_IMM8},
+ {BFD_RELOC_NIOS2_HI16, R_NIOS2_HI16},
+ {BFD_RELOC_NIOS2_LO16, R_NIOS2_LO16},
+ {BFD_RELOC_NIOS2_HIADJ16, R_NIOS2_HIADJ16},
+ {BFD_RELOC_32, R_NIOS2_BFD_RELOC_32},
+ {BFD_RELOC_16, R_NIOS2_BFD_RELOC_16},
+ {BFD_RELOC_8, R_NIOS2_BFD_RELOC_8},
+ {BFD_RELOC_NIOS2_GPREL, R_NIOS2_GPREL},
+ {BFD_RELOC_VTABLE_INHERIT, R_NIOS2_GNU_VTINHERIT},
+ {BFD_RELOC_VTABLE_ENTRY, R_NIOS2_GNU_VTENTRY},
+ {BFD_RELOC_NIOS2_UJMP, R_NIOS2_UJMP},
+ {BFD_RELOC_NIOS2_CJMP, R_NIOS2_CJMP},
+ {BFD_RELOC_NIOS2_CALLR, R_NIOS2_CALLR},
+ {BFD_RELOC_NIOS2_ALIGN, R_NIOS2_ALIGN},
+};
+
+/* Given a BFD reloc type, return a howto structure. */
+
+static reloc_howto_type *
+nios2_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ int i;
+ for (i = 0;
+ i < (int) (sizeof (nios2_reloc_map) / sizeof (struct elf_reloc_map));
+ ++i)
+ {
+ if (nios2_reloc_map[i].bfd_val == code)
+ return &elf_nios2_howto_table_rel[(int) nios2_reloc_map[i].elf_val];
+ }
+
+ return NULL;
+}
+
+/* Helper function for nios2_elf32_info_to_howto */
+
+static reloc_howto_type *
+nios2_elf32_rtype_to_howto (unsigned int r_type,
+ bfd_boolean rela_p ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (r_type < R_NIOS2_ILLEGAL);
+ return &elf_nios2_howto_table_rel[r_type];
+}
+
+/* Given a ELF32 relocation, fill in a arelent structure */
+
+static void
+nios2_elf32_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ cache_ptr->howto = nios2_elf32_rtype_to_howto (r_type, FALSE);
+
+ // FIXME - do we need to do anything else here???
+}
+
+/* The assembler has output long jmp/call sequences for all calls
+ * and pc-relative branches that it cannot guarantee are within
+ * range, so the linker must attempt to "relax" these sequences to
+ * short branches and calls if it can. Since we only relax in one
+ * direction - long to short - we don't need to see whether each
+ * relaxation invalidates any others
+ *
+ *
+ **/
+static bfd_boolean
+nios2_elf32_relax_section (bfd * abfd,
+ asection * sec,
+ struct bfd_link_info *link_info, bfd_boolean * again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ /* If this is the first time we have been called for this section,
+ initialize the cooked size. */
+ if (sec->size == 0)
+ sec->size = sec->rawsize;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, (void *) NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ /* Walk through them looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+
+ /* If this isn't something that can be relaxed, then ignore
+ this reloc. */
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_NIOS2_UJMP
+ && ELF32_R_TYPE (irel->r_info) != (int) R_NIOS2_CJMP
+ && ELF32_R_TYPE (irel->r_info) != (int) R_NIOS2_CALLR)
+ {
+ continue;
+ }
+
+ /* Get the section contents if we haven't done so already. */
+ if (contents == NULL)
+ {
+ /* Get cached copy if it exists. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ /* Go get them off disk. */
+ contents = (bfd_byte *) bfd_malloc (sec->rawsize);
+ if (contents == NULL)
+ goto error_return;
+
+ if (!bfd_get_section_contents (abfd, sec, contents,
+ (file_ptr) 0, sec->rawsize))
+ goto error_return;
+ }
+ }
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ else if (isym->st_shndx == SHN_ABS)
+ sym_sec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ sym_sec = bfd_com_section_ptr;
+ else
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ symval = (isym->st_value
+ + sym_sec->output_section->vma + sym_sec->output_offset);
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry *h;
+
+ /* An external symbol. */
+ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[indx];
+ BFD_ASSERT (h != NULL);
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ {
+ /* This appears to be a reference to an undefined
+ symbol. Just ignore it--it will be caught by the
+ regular reloc processing. */
+ continue;
+ }
+
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+
+ /* For simplicity of coding, we are going to modify the section
+ contents, the section relocs, and the BFD symbol table. We
+ must tell the rest of the code not to free up this
+ information. It would be possible to instead create a table
+ of changes which have to be made, as is done in coff-mips.c;
+ that would be more work, but would require less memory when
+ the linker is run. */
+
+ /* try to turn :
+ * movhi at, %hi(symbol)
+ * movui at, %lo(symbol)
+ * callr at
+ * into:
+ * call symbol
+ */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_NIOS2_CALLR)
+ {
+ bfd_vma targ_addr = symval + irel->r_addend;
+ bfd_vma curr_addr = (sec->output_section->vma + sec->output_offset);
+ bfd_vma targ_page, curr_page;
+ targ_page = targ_addr & 0xf0000000;
+ curr_page = curr_addr & 0xf0000000;
+
+ if (targ_page == curr_page)
+ {
+ /* change the opcode to a call */
+ bfd_put_32 (abfd, OP_MATCH_CALL, contents + irel->r_offset);
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_NIOS2_CALL26);
+
+ /* delete the next two instructions */
+ if (!nios2_elf32_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 4, 8))
+ goto error_return;
+
+ /* NG FIXME - I'm putting this in for now, but I don't think we need it */
+ *again = TRUE;
+ }
+ }
+
+ /* try to turn :
+ * movhi at, %hi(symbol)
+ * movui at, %lo(symbol)
+ * jmp at
+ * into:
+ * br symbol
+ */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_NIOS2_UJMP)
+ {
+ bfd_vma pcrel_offset;
+ Elf_Internal_Rela *irelalign = NULL;
+ Elf_Internal_Rela *irela = elf_section_data (sec)->relocs;
+ Elf_Internal_Rela *irelend = irel + sec->reloc_count;
+
+ for (; irela < irelend; irela++)
+ {
+ if (ELF32_R_TYPE (irela->r_info) == (int) R_NIOS2_ALIGN
+ && irela->r_offset > irel->r_offset + 4
+ && 8 < (1 << irela->r_addend))
+ {
+ irelalign = irela;
+ break;
+ }
+ }
+
+ /* calculate the pcrelative offset from current location */
+ pcrel_offset = symval;
+ pcrel_offset -= (sec->output_section->vma + sec->output_offset);
+ pcrel_offset += irel->r_addend;
+
+ /* we need to compute the pcrel_offset from the next instruction */
+ pcrel_offset -= (irel->r_offset + 4);
+
+ /* does this value fit in 16 bits */
+ if ((irelalign == NULL && (long) pcrel_offset <= 0x8004
+ && (long) pcrel_offset >= -0x8000) || (irelalign != NULL
+ && (long) pcrel_offset
+ <= 0x7ffc
+ && (long) pcrel_offset
+ >= -0x8000))
+ {
+ /* change the opcode to an unconditional branch */
+ bfd_put_32 (abfd, OP_MATCH_BR, contents + irel->r_offset);
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_NIOS2_PCREL16);
+
+ /* delete the next two instructions */
+ if (!nios2_elf32_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 4, 8))
+ goto error_return;
+
+ /* NG FIXME - I'm putting this in for now, but I don't think we need it */
+ *again = TRUE;
+ }
+ }
+
+ /* try to turn :
+ * b{cond} a, b skip
+ * movhi at, %hi(symbol)
+ * movui at, %lo(symbol)
+ * jmp at
+ * skip:
+ * ...
+ * into:
+ * br{opp_cond} a, b, symbol
+ */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_NIOS2_CJMP)
+ {
+ bfd_vma pcrel_offset;
+ Elf_Internal_Rela *irelalign = NULL;
+ Elf_Internal_Rela *irela = elf_section_data (sec)->relocs;
+ Elf_Internal_Rela *irelend = irel + sec->reloc_count;
+
+ for (; irela < irelend; irela++)
+ {
+ if (ELF32_R_TYPE (irela->r_info) == (int) R_NIOS2_ALIGN
+ && irela->r_offset > irel->r_offset + 4
+ && 8 < (1 << irela->r_addend))
+ {
+ irelalign = irela;
+ break;
+ }
+ }
+
+ /* calculate the pcrelative offset from current location */
+ pcrel_offset = symval;
+ pcrel_offset -= (sec->output_section->vma + sec->output_offset);
+ pcrel_offset += irel->r_addend;
+
+ /* we need to compute the pcrel_offset from this instruction
+ * ie the movhi */
+ pcrel_offset -= (irel->r_offset);
+
+ /* does this value fit in 16 bits */
+ if ((irelalign == NULL && (long) pcrel_offset <= 0x8008
+ && (long) pcrel_offset >= -0x8000) || (irelalign != NULL
+ && (long) pcrel_offset
+ <= 0x7ffc
+ && (long) pcrel_offset
+ >= -0x8000))
+ {
+ unsigned long opcode, op_a, op_b;
+ /* get the conditional branch opcode */
+ opcode = bfd_get_32 (abfd, contents + irel->r_offset - 4);
+ /* reverse the condition */
+ switch (opcode & OP_MASK_OP)
+ {
+ case OP_MATCH_BEQ:
+ opcode = (opcode & ~OP_MASK_OP) | OP_MATCH_BNE;
+ break;
+ case OP_MATCH_BNE:
+ opcode = (opcode & ~OP_MASK_OP) | OP_MATCH_BEQ;
+ break;
+ case OP_MATCH_BGE:
+ case OP_MATCH_BGEU:
+ case OP_MATCH_BLT:
+ case OP_MATCH_BLTU:
+ /* swap the operands */
+ op_a = (opcode & OP_MASK_RRT) << 5;
+ op_b = (opcode & OP_MASK_RRS) >> 5;
+ opcode =
+ (opcode & ~(OP_MASK_RRS | OP_MASK_RRT)) | op_a | op_b;
+ break;
+ default:
+ fprintf (stderr,
+ "relaxation error - expecting conditional branch, aborting\n");
+ abort ();
+ break;
+ }
+
+ /* we must set the branch target to zero so that the skip over the jmp doesn't get
+ * added to the jmp */
+ opcode = opcode & (~OP_MASK_IMM16);
+
+ /* change the opcode to the reversed conditional branch */
+ bfd_put_32 (abfd, opcode, contents + irel->r_offset - 4);
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_NIOS2_PCREL16);
+
+ /* this relocation's offset has also been reduced by 4 bytes */
+ irel->r_offset -= 4;
+
+ /* delete the next three instructions */
+ if (!nios2_elf32_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 4, 12))
+ goto error_return;
+
+ /* NG FIXME - I'm putting this in for now, but I don't think we need it */
+ *again = TRUE;
+ }
+ }
+
+ /* otherwise, leave alone */
+ }
+
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (!link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (!link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+
+ return TRUE;
+
+error_return:
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return FALSE;
+}
+
+/* Delete some bytes from a section while relaxing.
+ * Copied from mn10200 port */
+
+static bfd_boolean
+nios2_elf32_relax_delete_bytes (bfd * abfd,
+ asection * sec, bfd_vma addr, int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ Elf_Internal_Rela *irelalign;
+ bfd_vma toaddr;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+ asection *asec;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ /* The deletion must stop at the next ALIGN reloc for an aligment
+ power larger than the number of bytes we are deleting. */
+
+ irelalign = NULL;
+ /* +1 because we need to readjust symbols at end of section */
+ toaddr = sec->size + 1;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ for (; irel < irelend; irel++)
+ {
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_NIOS2_ALIGN
+ && irel->r_offset > addr && count < (1 << irel->r_addend))
+ {
+ irelalign = irel;
+ /* +1 because we need to readjust symbols at end of section */
+ toaddr = irel->r_offset + 1;
+ break;
+ }
+ }
+
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count,
+ (size_t) ((toaddr - 1) - addr - count));
+
+ if (irelalign == NULL)
+ sec->size -= count;
+ else
+ {
+ int i;
+
+#define NOP_OPCODE (0x0001883a)
+
+ BFD_ASSERT ((count & 3) == 0);
+ for (i = 0; i < count; i += 4)
+ bfd_put_32 (abfd, (bfd_vma) NOP_OPCODE,
+ contents + (toaddr - 1) - count + i);
+ }
+
+ /* get the symbol table */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+
+ /* Adjust all the reloc offsets in this section. */
+ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ {
+ /* Get the new reloc address. */
+ if ((irel->r_offset > addr && irel->r_offset < toaddr))
+ irel->r_offset -= count;
+ }
+
+ /* Adjust relocations against targets in this section whose positions
+ * have moved as a result of the relaxation */
+
+ for (asec = abfd->sections; asec; asec = asec->next)
+ {
+ irelend = elf_section_data (asec)->relocs + asec->reloc_count;
+ for (irel = elf_section_data (asec)->relocs; irel < irelend; irel++)
+ {
+ Elf_Internal_Sym *sym;
+ /* if the symbol which this reloc is against doesn't change
+ * we need to change the reloc addend */
+
+ sym = isym + ELF32_R_SYM (irel->r_info);
+ if (sym->st_shndx == sec_shndx
+ && !(sym->st_value > addr && sym->st_value < toaddr)
+ && sym->st_value + irel->r_addend > addr
+ && sym->st_value + irel->r_addend < toaddr)
+ {
+ irel->r_addend -= count;
+ }
+
+ }
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr && isym->st_value < toaddr)
+ isym->st_value -= count;
+
+
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+ if ((sym_hash->root.type == bfd_link_hash_defined
+ || sym_hash->root.type == bfd_link_hash_defweak)
+ && sym_hash->root.u.def.section == sec
+ && sym_hash->root.u.def.value > addr
+ && sym_hash->root.u.def.value < toaddr)
+ {
+ sym_hash->root.u.def.value -= count;
+ }
+ }
+
+ return TRUE;
+}
+
+struct bfd_link_info *nios2_link_info = NULL;
+
+/*
+void
+_bfd_set_link_info (info)
+ struct bfd_link_info *info;
+{
+ nios2_link_info = info;
+}
+*/
+
+bfd_boolean linker_force_make_executable = FALSE;
+
+/*
+void
+_bfd_set_force_make_executable (force)
+ bfd_boolean force;
+{
+ linker_force_make_executable = force;
+}
+*/
+
+/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
+ dangerous relocation. */
+
+static bfd_boolean
+nios2_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp, struct bfd_link_info *info)
+{
+
+ bfd_boolean gp_found;
+ struct bfd_hash_entry *h;
+ struct bfd_link_hash_entry *lh;
+
+ /* If we've already figured out what GP will be, just return it. */
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp)
+ return TRUE;
+
+ h = bfd_hash_lookup (&info->hash->table, "_gp", FALSE, FALSE);
+ lh = (struct bfd_link_hash_entry *) h;
+lookup:
+ if (lh)
+ {
+ switch (lh->type)
+ {
+ case bfd_link_hash_undefined:
+ case bfd_link_hash_undefweak:
+ case bfd_link_hash_common:
+ gp_found = FALSE;
+ break;
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ gp_found = TRUE;
+ *pgp = lh->u.def.value;
+ break;
+ case bfd_link_hash_indirect:
+ case bfd_link_hash_warning:
+ lh = lh->u.i.link;
+ /* @@FIXME ignoring warning for now */
+ goto lookup;
+ case bfd_link_hash_new:
+ default:
+ abort ();
+ }
+ }
+ else
+ gp_found = FALSE;
+
+ if (!gp_found)
+ {
+ /* Only get the error once. */
+ *pgp = 4;
+ _bfd_set_gp_value (output_bfd, *pgp);
+ return FALSE;
+ }
+
+ _bfd_set_gp_value (output_bfd, *pgp);
+
+ return TRUE;
+}
+
+/* We have to figure out the gp value, so that we can adjust the
+ symbol value correctly. We look up the symbol _gp in the output
+ BFD. If we can't find it, we're stuck. We cache it in the ELF
+ target data. We don't need to adjust the symbol value for an
+ external symbol if we are producing relocatable output. */
+
+static bfd_reloc_status_type
+nios2_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
+ char **error_message, bfd_vma *pgp, struct bfd_link_info *info)
+{
+ if (bfd_is_und_section (symbol->section) && !relocatable)
+ {
+ *pgp = 0;
+ return bfd_reloc_undefined;
+ }
+
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp == 0 && (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0))
+ {
+ /* if this is called without link_info, then
+ we cannot be doing a final link */
+ if (info == NULL)
+ relocatable = TRUE;
+
+ if (relocatable)
+ {
+ /* Make up a value. */
+ *pgp = symbol->section->output_section->vma + 0x4000;
+ _bfd_set_gp_value (output_bfd, *pgp);
+ }
+ else if (!nios2_elf_assign_gp (output_bfd, pgp, info))
+ {
+ *error_message =
+ (char *)
+ _("global pointer relative relocation when _gp not defined");
+ return bfd_reloc_dangerous;
+ }
+ }
+
+ return bfd_reloc_ok;
+}
+
+
+/* Relocations that require special handling */
+
+/* This is for relocations used only when relaxing to ensure
+ * changes in size of section don't screw up .align */
+static bfd_reloc_status_type
+nios2_elf32_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED,
+ asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+nios2_elf32_hi16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol, void *data,
+ asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ /* FIXME: See bfd_perform_relocation. Is this right? */
+ return bfd_reloc_ok;
+
+ return nios2_elf32_do_hi16_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_lo16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
+{
+/* This part is from bfd_elf_generic_reloc. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ /* FIXME: See bfd_perform_relocation. Is this right? */
+ return bfd_reloc_ok;
+
+ return nios2_elf32_do_lo16_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_hiadj16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+/* This part is from bfd_elf_generic_reloc. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ /* FIXME: See bfd_perform_relocation. Is this right? */
+ return bfd_reloc_ok;
+
+ return nios2_elf32_do_hiadj16_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ +
+ symbol->section->output_section->
+ vma +
+ symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_pcrel16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+/* This part is from bfd_elf_generic_reloc. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ /* FIXME: See bfd_perform_relocation. Is this right? */
+ return bfd_reloc_ok;
+
+ return nios2_elf32_do_pcrel16_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ +
+ symbol->section->output_section->
+ vma +
+ symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_call26_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
+{
+/* This part is from bfd_elf_generic_reloc. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ /* FIXME: See bfd_perform_relocation. Is this right? */
+ return bfd_reloc_ok;
+
+ return nios2_elf32_do_call26_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ +
+ symbol->section->output_section->
+ vma +
+ symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_gprel_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd, char **msg)
+{
+ bfd_vma relocation;
+ bfd_vma gp;
+ bfd_reloc_status_type r;
+
+
+/* This part is from bfd_elf_generic_reloc. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ /* FIXME: See bfd_perform_relocation. Is this right? */
+ return bfd_reloc_ok;
+
+ relocation = symbol->value
+ + symbol->section->output_section->vma + symbol->section->output_offset;
+
+ if ((r =
+ nios2_elf_final_gp (abfd, symbol, FALSE, msg, &gp,
+ nios2_link_info)) == bfd_reloc_ok)
+ {
+ relocation = relocation + reloc_entry->addend - gp;
+ reloc_entry->addend = 0;
+ if ((signed) relocation < -32768 || (signed) relocation > 32767)
+ {
+ *msg = _("global pointer relative address out of range");
+ r = bfd_reloc_outofrange;
+ }
+ else
+ {
+ r = nios2_elf32_do_gprel_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ relocation, reloc_entry->addend);
+ }
+ }
+
+ return r;
+}
+
+static bfd_reloc_status_type
+nios2_elf32_ujmp_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd, char **msg ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ /* FIXME: See bfd_perform_relocation. Is this right? */
+ return bfd_reloc_ok;
+
+ return nios2_elf32_do_ujmp_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_cjmp_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd, char **msg ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ /* FIXME: See bfd_perform_relocation. Is this right? */
+ return bfd_reloc_ok;
+
+ return nios2_elf32_do_cjmp_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_callr_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd, char **msg ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ /* FIXME: See bfd_perform_relocation. Is this right? */
+ return bfd_reloc_ok;
+
+
+ return nios2_elf32_do_callr_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ +
+ symbol->section->output_section->
+ vma +
+ symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+/* Do the relocations which require special handling */
+
+static bfd_reloc_status_type
+nios2_elf32_do_hi16_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
+ bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
+{
+ symbol_value = symbol_value + addend;
+ addend = 0;
+ symbol_value = (symbol_value >> 16) & 0xffff;
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_value, addend);
+}
+
+
+static bfd_reloc_status_type
+nios2_elf32_do_lo16_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
+ bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
+{
+ symbol_value = symbol_value + addend;
+ addend = 0;
+ symbol_value = symbol_value & 0xffff;
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_value, addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_hiadj16_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data, bfd_vma offset,
+ bfd_vma symbol_value, bfd_vma addend)
+{
+ symbol_value = symbol_value + addend;
+ addend = 0;
+ symbol_value =
+ ((symbol_value >> 16) & 0xffff) + ((symbol_value >> 15) & 0x01);
+ return _bfd_final_link_relocate (howto, abfd, input_section, data, offset,
+ symbol_value, addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_pcrel16_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
+ bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
+{
+ // NIOS2 pc relative relocations are relative to the next 32-bit instruction so we need
+ // to subtract 4 before doing a final_link_relocate
+ symbol_value = symbol_value + addend - 4;
+ addend = 0;
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_value, addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_call26_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
+ bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
+{
+ /* check that the relocation is in the same page as the current address */
+ if (((symbol_value + addend) & 0xf0000000)
+ != ((input_section->output_section->vma + offset) & 0xf0000000))
+ return bfd_reloc_overflow;
+
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_value, addend);
+}
+
+
+static bfd_reloc_status_type
+nios2_elf32_do_gprel_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
+ bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
+{
+ // because we need the output_bfd, the special handling is done
+ // in nios2_elf32_relocate_section or in nios2_elf32_gprel_relocate
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_value, addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_ujmp_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
+ bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
+{
+ bfd_vma symbol_lo16, symbol_hi16;
+ bfd_reloc_status_type r;
+ symbol_value = symbol_value + addend;
+ addend = 0;
+ symbol_hi16 = (symbol_value >> 16) & 0xffff;
+ symbol_lo16 = symbol_value & 0xffff;
+
+ r = _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_hi16, addend);
+
+ if (r == bfd_reloc_ok)
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset + 4, symbol_lo16, addend);
+
+ return r;
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_cjmp_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
+ bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
+{
+ bfd_vma symbol_lo16, symbol_hi16;
+ bfd_reloc_status_type r;
+ symbol_value = symbol_value + addend;
+ addend = 0;
+ symbol_hi16 = (symbol_value >> 16) & 0xffff;
+ symbol_lo16 = symbol_value & 0xffff;
+
+ r = _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_hi16, addend);
+
+ if (r == bfd_reloc_ok)
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset + 4, symbol_lo16, addend);
+
+ return r;
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_callr_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section ATTRIBUTE_UNUSED, bfd_byte *data,
+ bfd_vma offset, bfd_vma symbol_value, bfd_vma addend)
+{
+ bfd_vma symbol_lo16, symbol_hi16;
+ bfd_reloc_status_type r;
+ symbol_value = symbol_value + addend;
+ addend = 0;
+ symbol_hi16 = (symbol_value >> 16) & 0xffff;
+ symbol_lo16 = symbol_value & 0xffff;
+
+ r = _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_hi16, addend);
+
+ if (r == bfd_reloc_ok)
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset + 4, symbol_lo16, addend);
+
+ return r;
+}
+
+/*
+ The function nios2_elf32_relocate_section is used by the linker
+ to perform relocations
+*/
+static bfd_boolean
+nios2_elf32_relocate_section (bfd * output_bfd,
+ struct bfd_link_info *info,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
+ Elf_Internal_Rela * relocs,
+ Elf_Internal_Sym * local_syms,
+ asection ** local_sections)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+// size_t psymalloc = 0;
+// _bfd_generic_link_output_symbols(output_bfd, input_bfd, info, &psymalloc);
+ for (rel = relocs; rel < relend; rel++)
+ {
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ bfd_vma relocation;
+ bfd_vma gp;
+ bfd_reloc_status_type r = bfd_reloc_ok;
+ const char *name = NULL;
+ int r_type;
+ const char *msg;
+
+ msg = (const char *) NULL;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (info->relocatable)
+ {
+ /* This is a relocatable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+ rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+ continue;
+ }
+
+ /* This is a final link. */
+ howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info));
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+
+ relocation = (sec->output_section->vma
+ + sec->output_offset + sym->st_value);
+
+ // this ensures that relocations against duplicated symbols
+ // in merged sections that have been removed are fixed up against
+ // the remaining symbol and not the one that has been removed
+ if ((sec->flags & SEC_MERGE)
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ rel->r_addend =
+ _bfd_elf_rel_local_sym (output_bfd, sym, &sec, rel->r_addend);
+ rel->r_addend -= relocation;
+ rel->r_addend += sec->output_section->vma + sec->output_offset;
+ }
+
+ name = bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name);
+
+ name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ name = h->root.root.string;
+
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ {
+ relocation = 0;
+ }
+ else
+ {
+ if (!((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset, TRUE)))
+ return FALSE;
+ relocation = 0;
+ }
+ }
+
+ if (howto != NULL)
+ {
+ switch (howto->type)
+ {
+ case R_NIOS2_HI16:
+ r =
+ nios2_elf32_do_hi16_relocate (input_bfd, howto, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+ case R_NIOS2_LO16:
+ r =
+ nios2_elf32_do_lo16_relocate (input_bfd, howto, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+ case R_NIOS2_HIADJ16:
+ r =
+ nios2_elf32_do_hiadj16_relocate (input_bfd, howto,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ case R_NIOS2_PCREL16:
+ r =
+ nios2_elf32_do_pcrel16_relocate (input_bfd, howto,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ case R_NIOS2_GPREL:
+ // turns an absolute address into a gp-relative address
+ if (!nios2_elf_assign_gp (output_bfd, &gp, info))
+ {
+ msg =
+ _
+ ("global pointer relative relocation when _gp not defined");
+ r = bfd_reloc_dangerous;
+ }
+ else
+ {
+ relocation = relocation + rel->r_addend - gp;
+ rel->r_addend = 0;
+ if ((signed) relocation < -32768
+ || (signed) relocation > 32767)
+ {
+ msg = _("global pointer relative address out of range");
+ r = bfd_reloc_outofrange;
+ }
+ else
+ {
+ r =
+ _bfd_final_link_relocate (howto, input_bfd,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ }
+ }
+
+ break;
+ case R_NIOS2_UJMP:
+ r =
+ nios2_elf32_do_ujmp_relocate (input_bfd, howto, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+ case R_NIOS2_CJMP:
+ r =
+ nios2_elf32_do_cjmp_relocate (input_bfd, howto, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+ case R_NIOS2_CALLR:
+ r =
+ nios2_elf32_do_callr_relocate (input_bfd, howto,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ case R_NIOS2_CALL26:
+ r =
+ nios2_elf32_do_call26_relocate (input_bfd, howto,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ case R_NIOS2_ALIGN:
+ r = bfd_reloc_ok;
+ /* comment - for symmetry this would be
+ r = nios2_elf32_do_ignore_reloc (input_bfd, howto, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ but do_ignore_reloc would do no more than return bfd_reloc_ok */
+ break;
+ default:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+ }
+ }
+ else
+ {
+ r = bfd_reloc_notsupported;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
+ if (name == NULL || *name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset);
+ break;
+
+ case bfd_reloc_undefined:
+ r = info->callbacks->undefined_symbol
+ (info, name, input_bfd, input_section, rel->r_offset, TRUE);
+ break;
+
+ case bfd_reloc_outofrange:
+ if (msg == NULL)
+ msg = _("relocation out of range");
+ break;
+
+ case bfd_reloc_notsupported:
+ if (msg == NULL)
+ msg = _("unsupported relocation");
+ break;
+
+ case bfd_reloc_dangerous:
+ if (msg == NULL)
+ msg = _("dangerous relocation");
+ break;
+
+ default:
+ if (msg == NULL)
+ msg = _("unknown error");
+ break;
+ }
+
+ if (msg)
+ {
+ r = info->callbacks->warning
+ (info, msg, name, input_bfd, input_section, rel->r_offset);
+ return linker_force_make_executable;
+ }
+ }
+ }
+ return TRUE;
+}
+
+
+
+/* Handle an NIOS2 specific section when reading an object file. This
+ is called when elfcode.h finds a section with an unknown type.
+ FIXME: We need to handle the SHF_NIOS2_GPREL flag */
+
+static bfd_boolean
+nios2_elf32_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr *hdr, const char *name, int shindex)
+{
+ asection *newsect;
+
+ /* NG - I'm keeping this code commented out at the moment
+ in case we add a .mdebug section */
+
+ /*
+ switch (hdr->sh_type)
+ {
+ case SHT_NIOS2_DEBUG:
+ if (strcmp (name, ".mdebug") != 0)
+ return FALSE;
+ break;
+ default:
+ return FALSE;
+ }
+ */
+
+ if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ return FALSE;
+
+ newsect = hdr->bfd_section;
+
+ /* ditto */
+ /*
+ if (hdr->sh_type == SHT_NIOS2_DEBUG)
+ {
+ if (! bfd_set_section_flags (abfd, newsect,
+ (bfd_get_section_flags (abfd, newsect)
+ | SEC_DEBUGGING)))
+ return FALSE;
+ }
+ */
+ return TRUE;
+}
+
+/* Convert NIOS2 specific section flags to bfd internal section flags. */
+
+static bfd_boolean
+nios2_elf32_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
+{
+ if (hdr->sh_flags & SHF_NIOS2_GPREL)
+ *flags |= SEC_SMALL_DATA;
+
+ return TRUE;
+}
+
+/* Set the correct type for an NIOS2 ELF section. We do this by the
+ section name, which is a hack, but ought to work. */
+
+static bfd_boolean
+nios2_elf32_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *hdr, asection *sec)
+{
+ register const char *name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (strcmp (name, ".mdebug") == 0)
+ {
+ /* we don't yet have an .mdebug section, but I'm leaving this here
+ in case we ever do
+ hdr->sh_type = SHT_NIOS2_DEBUG;
+
+ if ((abfd->flags & DYNAMIC) != 0 )
+ hdr->sh_entsize = 0;
+ else
+ hdr->sh_entsize = 1;
+ */
+ }
+ else if ((sec->flags & SEC_SMALL_DATA)
+ || strcmp (name, ".sdata") == 0
+ || strcmp (name, ".sbss") == 0
+ || strcmp (name, ".lit4") == 0 || strcmp (name, ".lit8") == 0)
+ hdr->sh_flags |= SHF_NIOS2_GPREL;
+
+ return TRUE;
+}
+
+/* Look through the relocs for a section during the first phase.
+ Since we don't do .gots or .plts, we just need to consider the
+ virtual table relocs for gc. */
+
+static bfd_boolean
+nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, const Elf_Internal_Rela *relocs)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ sym_hashes_end =
+ sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
+ if (!elf_bad_symtab (abfd))
+ sym_hashes_end -= symtab_hdr->sh_info;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_NIOS2_GNU_VTINHERIT:
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return FALSE;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_NIOS2_GNU_VTENTRY:
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+asection *
+nios2_elf32_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela *rel, struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_NIOS2_GNU_VTINHERIT:
+ case R_NIOS2_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+
+ default:
+ break;
+ }
+ }
+ }
+ else
+ return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+
+ return NULL;
+}
+
+/*
+ NG ??? I'm marking the sections as standalone ie. I'm linking for
+ standalone embedded applications, not for UNIX System V or any other
+ OS/ABI - this may need to change when we deal with embedded PIC or
+ dynamic linking
+*/
+
+static void
+nios2_elf32_post_process_headers (bfd *abfd,
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
+{
+ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
+
+ i_ehdrp = elf_elfheader (abfd);
+ i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_STANDALONE;
+}
+
+#define ELF_ARCH bfd_arch_nios2
+#define ELF_MACHINE_CODE EM_ALTERA_NIOS2
+
+/* for now we just make this 1, as we have no MMU in New Jersey */
+
+#define ELF_MAXPAGESIZE 1
+
+/* relocation table lookup macros */
+
+#define bfd_elf32_bfd_reloc_type_lookup nios2_elf32_bfd_reloc_type_lookup
+
+/* JUMP_TABLE_LINK macros */
+
+#define bfd_elf32_bfd_relax_section nios2_elf32_relax_section
+
+/* elf_info_to_howto (using RELA relocations) */
+
+#define elf_info_to_howto nios2_elf32_info_to_howto
+
+/* elf backend functions */
+
+#define elf_backend_can_gc_sections 1
+
+#define elf_backend_relocate_section nios2_elf32_relocate_section
+#define elf_backend_section_from_shdr nios2_elf32_section_from_shdr
+#define elf_backend_section_flags nios2_elf32_section_flags
+#define elf_backend_fake_sections nios2_elf32_fake_sections
+#define elf_backend_post_process_headers nios2_elf32_post_process_headers
+#define elf_backend_check_relocs nios2_elf32_check_relocs
+
+#define elf_backend_gc_mark_hook nios2_elf32_gc_mark_hook
+
+
+
+/* Support for SGI-ish mips targets. */
+#define TARGET_LITTLE_SYM bfd_elf32_littlenios2_vec
+#define TARGET_LITTLE_NAME "elf32-littlenios2"
+#define TARGET_BIG_SYM bfd_elf32_bignios2_vec
+#define TARGET_BIG_NAME "elf32-bignios2"
+
+#include "elf32-target.h"
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 1b8c8d7..c66a23d 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -4733,6 +4733,39 @@ ENUMDOC
msp430 specific relocation codes
ENUM
+ BFD_RELOC_NIOS2_S16
+ENUMX
+ BFD_RELOC_NIOS2_U16
+ENUMX
+ BFD_RELOC_NIOS2_CALL26
+ENUMX
+ BFD_RELOC_NIOS2_IMM5
+ENUMX
+ BFD_RELOC_NIOS2_CACHE_OPX
+ENUMX
+ BFD_RELOC_NIOS2_IMM6
+ENUMX
+ BFD_RELOC_NIOS2_IMM8
+ENUMX
+ BFD_RELOC_NIOS2_HI16
+ENUMX
+ BFD_RELOC_NIOS2_LO16
+ENUMX
+ BFD_RELOC_NIOS2_HIADJ16
+ENUMX
+ BFD_RELOC_NIOS2_GPREL
+ENUMX
+ BFD_RELOC_NIOS2_UJMP
+ENUMX
+ BFD_RELOC_NIOS2_CJMP
+ENUMX
+ BFD_RELOC_NIOS2_CALLR
+ENUMX
+ BFD_RELOC_NIOS2_ALIGN
+ENUMDOC
+ Relocations used by the Altera Nios II core
+
+ENUM
BFD_RELOC_IQ2000_OFFSET_16
ENUMX
BFD_RELOC_IQ2000_OFFSET_21
diff --git a/bfd/targets.c b/bfd/targets.c
index 71e3337..d5f6d60 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -619,6 +619,8 @@ extern const bfd_target bfd_elf32_ntradbigmips_vec;
extern const bfd_target bfd_elf32_ntradlittlemips_vec;
extern const bfd_target bfd_elf32_openrisc_vec;
extern const bfd_target bfd_elf32_or32_big_vec;
+extern const bfd_target bfd_elf32_littlenios2_vec;
+extern const bfd_target bfd_elf32_bignios2_vec;
extern const bfd_target bfd_elf32_pj_vec;
extern const bfd_target bfd_elf32_pjl_vec;
extern const bfd_target bfd_elf32_powerpc_vec;
@@ -819,6 +821,8 @@ extern const bfd_target sco5_core_vec;
extern const bfd_target trad_core_vec;
extern const bfd_target bfd_elf32_am33lin_vec;
+extern const bfd_target bfd_elf32_littlenios2_vec;
+extern const bfd_target bfd_elf32_bignios2_vec;
static const bfd_target * const _bfd_target_vector[] =
{
#ifdef SELECT_VECS
@@ -923,6 +927,8 @@ static const bfd_target * const _bfd_target_vector[] =
&bfd_elf32_littlearm_vxworks_vec,
&bfd_elf32_littlemips_vec,
&bfd_elf32_littlemips_vxworks_vec,
+ &bfd_elf32_littlenios2_vec,
+ &bfd_elf32_bignios2_vec,
&bfd_elf32_m32c_vec,
&bfd_elf32_m32r_vec,
&bfd_elf32_m32rle_vec,
diff --git a/config.sub b/config.sub
index fab0aa3..462e7c6 100755
--- a/config.sub
+++ b/config.sub
@@ -270,7 +270,7 @@ case $basic_machine in
| mn10200 | mn10300 \
| mt \
| msp430 \
- | nios | nios2 \
+ | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| or32 \
| pdp10 | pdp11 | pj | pjl \
diff --git a/configure.in b/configure.in
index a4befda..f2e34c7 100644
--- a/configure.in
+++ b/configure.in
@@ -740,6 +740,9 @@ case "${target}" in
mips*-*-*)
noconfigdirs="$noconfigdirs gprof ${libgcj}"
;;
+ nios2*-*-*)
+ noconfigdirs="$noconfigdirs ld"
+ ;;
romp-*-*)
noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes target-libgloss ${libgcj}"
;;
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 14fd58b..eac9489 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -593,6 +593,7 @@ libiberty_h = $(INCLUDE_DIR)/libiberty.h
libbfd_h = $(BFD_SRC)/libbfd.h
remote_sim_h = $(INCLUDE_DIR)/gdb/remote-sim.h
demangle_h = $(INCLUDE_DIR)/demangle.h
+nios2_h = $(INCLUDE_DIR)/opcode/nios2.h
obstack_h = $(INCLUDE_DIR)/obstack.h
opcode_m68hc11_h = $(INCLUDE_DIR)/opcode/m68hc11.h
readline_h = $(READLINE_SRC)/readline.h
@@ -2399,6 +2400,7 @@ ms1-tdep.o: ms1-tdep.c $(defs_h) $(frame_h) $(frame_unwind_h) $(frame_base_h) \
$(trad_frame_h) $(inferior_h) $(dwarf2_frame_h) $(infcall_h) \
$(gdb_assert_h)
nbsd-tdep.o: nbsd-tdep.c $(defs_h) $(gdb_string_h) $(solib_svr4_h)
+nios2-tdep.o: nios2-tdep.c $(defs_h) $(symtab_h) $(frame_h) $(nios2_h)
nlmread.o: nlmread.c $(defs_h) $(bfd_h) $(symtab_h) $(symfile_h) \
$(objfiles_h) $(buildsym_h) $(stabsread_h) $(block_h)
nto-procfs.o: nto-procfs.c $(defs_h) $(gdb_dirent_h) $(exceptions_h) \
diff --git a/gdb/config/nios2/nios2.mt b/gdb/config/nios2/nios2.mt
new file mode 100644
index 0000000..63413b4
--- /dev/null
+++ b/gdb/config/nios2/nios2.mt
@@ -0,0 +1,4 @@
+# Target: Altera New Jersey Processor machine (NIOS2)
+TDEPFILES= nios2-tdep.o
+
+
diff --git a/gdb/config/nios2/tm-nios2.h b/gdb/config/nios2/tm-nios2.h
new file mode 100644
index 0000000..2962b6b
--- /dev/null
+++ b/gdb/config/nios2/tm-nios2.h
@@ -0,0 +1,28 @@
+/* Definitions to target GDB to New Jersey targets.
+ Copyright 1986, 1987, 1988, 1989, 1991, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2003
+ by Peter Brookes (pbrookes@altera.com)
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef TM_NIOS2_H
+#define TM_NIOS2_H
+
+#define GDB_MULTI_ARCH 1
+
+#endif /* TM_NIOS2_H */
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index dd2e719..7222f59 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -20,6 +20,7 @@ m68hc11*|m6811*) gdb_target_cpu=m68hc11 ;;
m68*) gdb_target_cpu=m68k ;;
m88*) gdb_target_cpu=m88k ;;
mips*) gdb_target_cpu=mips ;;
+nios2*) gdb_target_cpu=nios2 ;;
powerpc*) gdb_target_cpu=powerpc ;;
sparc*) gdb_target_cpu=sparc ;;
thumb*) gdb_target_cpu=arm ;;
@@ -155,6 +156,8 @@ mn10300-*-*) gdb_target=mn10300 ;;
mt-*-*) gdb_target=mt ;;
+nios2*-*-*) gdb_target=nios2 ;;
+
powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
gdb_target=nbsd ;;
powerpc-*-openbsd*) gdb_target=obsd ;;
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 9748c95..b3fb5f8 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -280,6 +280,7 @@ linux-ia64-low.o: linux-ia64-low.c $(linux_low_h) $(server_h)
linux-m32r-low.o: linux-m32r-low.c $(linux_low_h) $(server_h)
linux-mips-low.o: linux-mips-low.c $(linux_low_h) $(server_h) \
$(gdb_proc_service_h)
+linux-nios2-low.o: linux-nios2-low.c $(linux_low_h) $(server_h)
linux-ppc-low.o: linux-ppc-low.c $(linux_low_h) $(server_h)
linux-ppc64-low.o: linux-ppc64-low.c $(linux_low_h) $(server_h)
linux-s390-low.o: linux-s390-low.c $(linux_low_h) $(server_h)
@@ -318,6 +319,9 @@ reg-m68k.c : $(srcdir)/../regformats/reg-m68k.dat $(regdat_sh)
reg-mips.o : reg-mips.c $(regdef_h)
reg-mips.c : $(srcdir)/../regformats/reg-mips.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-mips.dat reg-mips.c
+reg-nios2.o : reg-nios2.c $(regdef_h)
+reg-nios2.c : $(srcdir)/../regformats/reg-nios2.dat $(regdat_sh)
+ sh $(regdat_sh) $(srcdir)/../regformats/reg-nios2.dat reg-nios2.c
reg-ppc.o : reg-ppc.c $(regdef_h)
reg-ppc.c : $(srcdir)/../regformats/reg-ppc.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-ppc.dat reg-ppc.c
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index 5a4792c..fdc847c 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -72,6 +72,10 @@ case "${target}" in
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
+ nios2-*-linux*) srv_regobj=reg-nios2.o
+ srv_tgtobj="linux-low.o linux-nios2-low.o"
+ srv_linux_usrregs=yes
+ ;;
powerpc64-*-linux*) srv_regobj=reg-ppc64.o
srv_tgtobj="linux-low.o linux-ppc64-low.o"
srv_linux_usrregs=yes
diff --git a/gdb/gdbserver/linux-nios2-low.c b/gdb/gdbserver/linux-nios2-low.c
new file mode 100644
index 0000000..1fab749
--- /dev/null
+++ b/gdb/gdbserver/linux-nios2-low.c
@@ -0,0 +1,89 @@
+/* GNU/Linux/Nios2 specific low level interface for the remote server for GDB */
+
+#include "server.h"
+#include "linux-low.h"
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#include <asm/ptrace.h>
+
+static int nios2_regmap[] =
+{
+ -1, PTR_R1 * 4, PTR_R2 * 4, PTR_R3 * 4,
+ PTR_R4 * 4, PTR_R5 * 4, PTR_R6 * 4, PTR_R7 * 4,
+ PTR_R8 * 4, PTR_R9 * 4, PTR_R10 * 4, PTR_R11 * 4,
+ PTR_R12 * 4, PTR_R13 * 4, PTR_R14 * 4, PTR_R15 * 4, /* reg 15 */
+ PTR_R16 * 4, PTR_R17 * 4, PTR_R18 * 4, PTR_R19 * 4,
+ PTR_R20 * 4, PTR_R21 * 4, PTR_R22 * 4, PTR_R23 * 4,
+ -1, -1, PTR_GP * 4, PTR_SP * 4,
+ PTR_FP * 4, -1, -1, PTR_RA * 4, /* reg 31 */
+ PTR_PC * 4, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1
+};
+
+#define nios2_num_regs (sizeof(nios2_regmap) / sizeof(nios2_regmap[0]))
+
+static int
+nios2_cannot_store_register (int regno)
+{
+ return (regno >= 33);
+}
+
+static int
+nios2_cannot_fetch_register (int regno)
+{
+ return (regno >= 33);
+}
+
+static CORE_ADDR
+nios2_get_pc ()
+{
+ unsigned long pc;
+ collect_register_by_name ("pc", &pc);
+ return pc;
+}
+
+static void
+nios2_set_pc (CORE_ADDR pc)
+{
+ unsigned long newpc = pc;
+ supply_register_by_name ("pc", &newpc);
+}
+
+#if 0
+static const unsigned long nios2_breakpoint = 0x003da03a;
+#else
+static const unsigned long nios2_breakpoint = 0x003b687a; /* Trap instr. w/imm=0x01 */
+#endif
+#define nios2_breakpoint_len 4
+
+static int
+nios2_breakpoint_at (CORE_ADDR where)
+{
+ unsigned long insn;
+
+ (*the_target->read_memory) (where, (char *) &insn, nios2_breakpoint_len);
+ if (insn == nios2_breakpoint)
+ return 1;
+
+ /* If necessary, recognize more trap instructions here. GDB only uses the
+ one. */
+ return 0;
+}
+
+struct linux_target_ops the_low_target = {
+ nios2_num_regs,
+ nios2_regmap,
+ nios2_cannot_fetch_register,
+ nios2_cannot_store_register,
+ nios2_get_pc,
+ nios2_set_pc,
+ (const char *) &nios2_breakpoint,
+ nios2_breakpoint_len,
+ NULL,
+ 0,
+ nios2_breakpoint_at,
+};
diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c
new file mode 100644
index 0000000..e0712dd
--- /dev/null
+++ b/gdb/nios2-tdep.c
@@ -0,0 +1,1610 @@
+/* Target-machine dependent code for Nios2, for GDB.
+ Copyright (C) 2003-2005
+ by Peter Brookes (pbrookes@altera.com)
+ and Andrew Draper (adraper@altera.com)
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "frame-base.h"
+#include "trad-frame.h"
+#include "dwarf2-frame.h"
+#include "symtab.h"
+#include "inferior.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "dis-asm.h"
+#include "regcache.h"
+#include "value.h"
+#include "symfile.h"
+#include "arch-utils.h"
+#include "floatformat.h"
+#include "gdb_assert.h"
+
+/* To get entry_point_address. */
+#include "objfiles.h"
+
+/* Nios II ISA specific encodings and macros */
+#include "opcode/nios2.h"
+
+/* Macros */
+
+#define Z_REGNUM 0 /* Zero */
+#define R2_REGNUM 2 /* used for return value */
+#define R3_REGNUM 3 /* used for return value */
+/* used for hidden zero argument to store ptr to struct return value */
+#define R4_REGNUM 4
+#define R7_REGNUM 7
+#define GP_REGNUM 26 /* Global Pointer */
+#undef SP_REGNUM
+#define SP_REGNUM 27 /* Stack Pointer */
+#undef FP_REGNUM
+#define FP_REGNUM 28 /* Frame Pointer */
+#define EA_REGNUM 29 /* Exception address */
+#define BA_REGNUM 30 /* Breakpoint return address */
+#define RA_REGNUM 31 /* Return address */
+#undef PC_REGNUM
+#define PC_REGNUM 32
+#define STATUS_REGNUM 33 /* Ctrl registers */
+#define ESTATUS_REGNUM 34
+#define BSTATUS_REGNUM 35
+#define IENABLE_REGNUM 36
+#define IPENDING_REGNUM 37
+#define CPUID_REGNUM 38
+#define PTEADDR_REGNUM 41
+#define TLBACC_REGNUM 42
+#define TLBMISC_REGNUM 43
+#define FIRST_ARGREG R4_REGNUM
+#define LAST_ARGREG R7_REGNUM
+/* Number of all registers */
+#define NIOS2_NUM_REGS (44)
+/* The maximum register number displayed to the user, */
+/* as a result of typing "info reg" at the gdb prompt */
+#define NIOS2_MAX_REG_DISPLAYED_REGNUM (38)
+
+#define NIOS2_OPCODE_SIZE 4
+
+/* Structures */
+struct register_info
+{
+ int size;
+ char *name;
+ struct type **type;
+};
+
+/* The current value in the register is the value in r[base] at the start of
+ * the function + offset ; unless base < 0 in which case it's unknown.
+ */
+typedef struct
+{
+ int reg;
+ unsigned int offset;
+
+} REG_VALUE;
+
+
+typedef struct
+{
+ int basereg;
+ CORE_ADDR addr;
+
+} REG_SAVED;
+
+struct nios2_unwind_cache
+{
+ /* The frame's base, optionally used by the high-level debug info. */
+ CORE_ADDR base;
+
+ /* The previous frame's inner most stack address. Used as this
+ frame ID's stack_addr. */
+ CORE_ADDR cfa;
+
+ /* The address of the first instruction in this function */
+ CORE_ADDR pc;
+
+ /* Which register holds the return address for the frame. */
+ int return_regnum;
+
+ /* Table indicating what changes have been made to each register */
+ REG_VALUE reg_value[NIOS2_NUM_REGS];
+
+ /* Table indicating where each register has been saved. */
+ REG_SAVED reg_saved[NIOS2_NUM_REGS];
+};
+
+
+/* Function prototypes */
+CORE_ADDR nios2_saved_pc_after_call (struct frame_info *fi);
+
+/* nios2_register_info_table[i] is the number of bytes of storage in
+ GDB's register array occupied by register i. */
+static struct register_info nios2_register_info_table[] = {
+ /* 0 */ {4, "zero", &builtin_type_uint32},
+ /* 1 */ {4, "at", &builtin_type_uint32},
+ /* 2 */ {4, "r2", &builtin_type_uint32},
+ /* 3 */ {4, "r3", &builtin_type_uint32},
+ /* 4 */ {4, "r4", &builtin_type_uint32},
+ /* 5 */ {4, "r5", &builtin_type_uint32},
+ /* 6 */ {4, "r6", &builtin_type_uint32},
+ /* 7 */ {4, "r7", &builtin_type_uint32},
+ /* 8 */ {4, "r8", &builtin_type_uint32},
+ /* 9 */ {4, "r9", &builtin_type_uint32},
+ /* 10 */ {4, "r10", &builtin_type_uint32},
+ /* 11 */ {4, "r11", &builtin_type_uint32},
+ /* 12 */ {4, "r12", &builtin_type_uint32},
+ /* 13 */ {4, "r13", &builtin_type_uint32},
+ /* 14 */ {4, "r14", &builtin_type_uint32},
+ /* 15 */ {4, "r15", &builtin_type_uint32},
+ /* 16 */ {4, "r16", &builtin_type_uint32},
+ /* 17 */ {4, "r17", &builtin_type_uint32},
+ /* 18 */ {4, "r18", &builtin_type_uint32},
+ /* 19 */ {4, "r19", &builtin_type_uint32},
+ /* 20 */ {4, "r20", &builtin_type_uint32},
+ /* 21 */ {4, "r21", &builtin_type_uint32},
+ /* 22 */ {4, "r22", &builtin_type_uint32},
+ /* 23 */ {4, "r23", &builtin_type_uint32},
+ /* 24 */ {4, "et", &builtin_type_uint32},
+ /* 25 */ {4, "bt", &builtin_type_uint32},
+ /* 26 */ {4, "gp", &builtin_type_uint32},
+ /* 27 */ {4, "sp", &builtin_type_uint32},
+ /* 28 */ {4, "fp", &builtin_type_uint32},
+ /* 29 */ {4, "ea", &builtin_type_uint32},
+ /* 30 */ {4, "ba", &builtin_type_uint32},
+ /* 31 */ {4, "ra", &builtin_type_uint32},
+ /* 32 */ {4, "pc", &builtin_type_uint32},
+ /* 33 */ {4, "status", &builtin_type_uint32},
+ /* 34 */ {4, "estatus", &builtin_type_uint32},
+ /* 35 */ {4, "bstatus", &builtin_type_uint32},
+ /* 36 */ {4, "ienable", &builtin_type_uint32},
+ /* 37 */ {4, "ipending", &builtin_type_uint32},
+ /* 38 */ {4, "cpuid", &builtin_type_uint32},
+ /* 39 */ {4, "ctl6", &builtin_type_uint32},
+ /* 40 */ {4, "ctl7", &builtin_type_uint32},
+ /* 41 */ {4, "pteaddr", &builtin_type_uint32},
+ /* 42 */ {4, "tlbacc", &builtin_type_uint32},
+ /* 43 */ {4, "tlbmisc", &builtin_type_uint32}
+};
+
+/* This array is a mapping from Dwarf-2 register
+ numbering to GDB's */
+static int nios2_dwarf2gdb_regno_map[] = {
+ 0, 1, 2, 3,
+ 4, 5, 6, 7,
+ 8, 9, 10, 11,
+ 12, 13, 14, 15,
+ 16, 17, 18, 19,
+ 20, 21, 22, 23,
+ 24, 25,
+ GP_REGNUM, /* 26 */
+ SP_REGNUM, /* 27 */
+ FP_REGNUM, /* 28 */
+ EA_REGNUM, /* 29 */
+ BA_REGNUM, /* 30 */
+ RA_REGNUM, /* 31 */
+ PC_REGNUM, /* 32 */
+ STATUS_REGNUM, /* 33 */
+ ESTATUS_REGNUM, /* 34 */
+ BSTATUS_REGNUM, /* 35 */
+ IENABLE_REGNUM, /* 36 */
+ IPENDING_REGNUM, /* 37 */
+ 38, 39, 40, 41, 42, 43
+};
+
+/* Dwarf-2 <-> GDB register numbers mapping. */
+int
+nios2_dwarf_reg_to_regnum (int dw_reg)
+{
+ if (dw_reg < 0 || dw_reg > NIOS2_NUM_REGS)
+ {
+ warning ("Dwarf-2 uses unmapped register #%d\n", dw_reg);
+ return dw_reg;
+ }
+
+ return nios2_dwarf2gdb_regno_map[dw_reg];
+}
+
+/* Same as read_memory_u6signed_integer, but don't report an error if
+ can't read. */
+int
+nios2_read_memory_unsigned_integer (CORE_ADDR memaddr, int len, ULONGEST *ret)
+{
+ char buf[sizeof (ULONGEST)];
+ int error;
+
+ error = target_read_memory (memaddr, buf, len);
+ if (error != 0)
+ return 0;
+ else
+ {
+ *ret = extract_unsigned_integer (buf, len);
+ return 1;
+ }
+}
+
+/* Find the name for the specified NIOS2 regno */
+static const char *
+nios2_register_name (int regno)
+{
+ /* Don't display any registers after NIOS2_MAX_REG_DISPLAYED_REGNUM */
+ if (regno < 0)
+ return NULL;
+ else if (regno > NIOS2_MAX_REG_DISPLAYED_REGNUM)
+ return NULL;
+ return nios2_register_info_table[regno].name;
+}
+
+/* Returns the default type for register N. */
+static struct type *
+nios2_register_type (struct gdbarch *gdbarch, int regno)
+{
+/* FIXME Do we need some checks on regno ? */
+ return *nios2_register_info_table[regno].type;
+}
+
+/* nios2_register_byte_table[i] is the offset into the register file of the
+ start of register number i. We initialize this from
+ nios2_register_info_table. */
+int nios2_register_byte_table[NIOS2_NUM_REGS];
+
+/* Index within `registers' of the first byte of the space for register REGNO. */
+int
+nios2_register_byte (int regno)
+{
+ return nios2_register_byte_table[regno];
+}
+
+/* Number of bytes of storage in the actual machine representation for
+ register 'regno'. */
+static int
+nios2_register_raw_size (int regno)
+{
+ return nios2_register_info_table[regno].size;
+}
+
+/* Number of bytes of storage in the program's representation for
+ register 'regno'. */
+static int
+nios2_register_virtual_size (int regno)
+{
+ return nios2_register_info_table[regno].size;
+}
+
+/* Return the GDB type object for the "standard" data type
+ of data in register 'regno'. */
+static struct type *
+nios2_register_virtual_type (int regno)
+{
+ return *nios2_register_info_table[regno].type;
+}
+
+/* Does this register need conversion betwen raw and virtual formats */
+int
+nios2_register_convertible (int regno)
+{
+ if (nios2_register_raw_size (regno) == nios2_register_virtual_size (regno))
+ return 0;
+ else
+ return 1;
+}
+
+
+
+/* Given a return value in `regcache' with a type `valtype',
+ extract and copy its value into `valbuf'. */
+/* FIXME: check this function*/
+void
+nios2_extract_return_value (struct type *valtype, struct regcache *regcache, void *valbuf)
+{
+#ifdef PORTINGTO61
+ int len = TYPE_LENGTH (valtype);
+
+ /* pointer types are returned in register r2,
+ up to 16-bit types in r2
+ up to 32-bit types in r2,r3 */
+ if (len <= nios2_register_raw_size (R2_REGNUM))
+ memcpy (valbuf, regbuf + REGISTER_BYTE (R2_REGNUM), len);
+ else if (len <= (nios2_register_raw_size (R2_REGNUM)
+ + nios2_register_raw_size (R3_REGNUM)))
+ memcpy (valbuf, regbuf + REGISTER_BYTE (R2_REGNUM), len);
+ else
+ {
+ /* Can I get the returned value here ? */
+ memset(valbuf, 0, len);
+ }
+#endif
+}
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format. */
+/* FIXME: check if required */
+void
+nios2_store_return_value (struct type *valtype, void *valbuf)
+{
+#ifdef PORTINGTO61
+ int len = TYPE_LENGTH (valtype);
+
+ /* return values of up to 8 bytes are returned in $r2 $r3 */
+
+ if (len <= nios2_register_raw_size (R2_REGNUM))
+ write_register_bytes (REGISTER_BYTE (R2_REGNUM),
+ valbuf,
+ len);
+ else if (len <= (nios2_register_raw_size (R2_REGNUM)
+ + nios2_register_raw_size (R3_REGNUM)))
+ write_register_bytes (REGISTER_BYTE (R2_REGNUM),
+ valbuf,
+ len);
+#endif
+}
+
+#ifdef PORTINGTO61
+
+/* Setup the function arguments for calling a function in the inferior. */
+static CORE_ADDR
+nios2_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int argreg;
+ int argnum;
+ struct stack_arg
+ {
+ int len;
+ char *val;
+ } *stack_args;
+ int nstack_args = 0;
+
+ stack_args = (struct stack_arg *) alloca (nargs * sizeof (struct stack_arg));
+
+ /* The lowest register number containing arguments */
+ argreg = FIRST_ARGREG;
+
+ /* Align the stack. It will be needed
+ if we call a function which has argument overflow. */
+ sp &= ~3;
+
+ /* If this function returns a struct which does not fit in the
+ return registers, we must pass a buffer to the function
+ which it can use to save the return value. */
+ if (struct_return)
+ write_register (R2_REGNUM, struct_addr);
+
+ /* FIXME: what about unions? */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ char *val = (char *) VALUE_CONTENTS (args[argnum]);
+ int len = TYPE_LENGTH (VALUE_TYPE (args[argnum]));
+ struct type *type = VALUE_TYPE (args[argnum]);
+ int olen;
+
+ if ((argreg <= LAST_ARGREG && len <= (LAST_ARGREG - argreg + 1) * DEPRECATED_REGISTER_SIZE)
+ || (TYPE_CODE (type) == TYPE_CODE_STRUCT))
+ {
+ /* Something that will fit entirely into registers or go on the stack. */
+ while (len > 0 && argreg <= LAST_ARGREG)
+ { write_register (argreg, extract_unsigned_integer (val, DEPRECATED_REGISTER_SIZE));
+
+ argreg++;
+ val += DEPRECATED_REGISTER_SIZE;
+ len -= DEPRECATED_REGISTER_SIZE;
+ }
+
+ /* Any remainder for the stack is noted below... */
+ }
+ else if (TYPE_CODE (VALUE_TYPE (args[argnum])) != TYPE_CODE_STRUCT
+ && len > DEPRECATED_REGISTER_SIZE)
+ {
+ /* All subsequent args go onto the stack. */
+ argnum = LAST_ARGREG + 1;
+ }
+
+ if (len > 0)
+ {
+ /* Note that this must be saved onto the stack */
+ stack_args[nstack_args].val = val;
+ stack_args[nstack_args].len = len;
+ nstack_args++;
+ }
+ }
+
+ /* We're done with registers and stack allocation. Now do the actual
+ stack pushes. */
+ while (nstack_args--)
+ {
+ sp -= stack_args[nstack_args].len;
+ write_memory (sp, stack_args[nstack_args].val, stack_args[nstack_args].len);
+ }
+
+ /* Return adjusted stack pointer. */
+ return sp;
+}
+
+/* Function: push_return_address (pc)
+ Set up the return address for the inferior function call.*/
+/* FIXME: Check if required */
+static CORE_ADDR
+nios2_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ write_register (RA_REGNUM, CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+/* Extract from an array regcache containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+/* FIXME: Check if required */
+
+static CORE_ADDR
+nios2_extract_struct_value_address (char *regbuf)
+{
+ return (extract_address ((regbuf) + REGISTER_BYTE (R4_REGNUM),
+ REGISTER_RAW_SIZE (R4_REGNUM)));
+}
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function. */
+
+/* FIXME: Check if required */
+static void
+nios2_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ write_register (R4_REGNUM, (addr));
+}
+#endif
+
+
+/* This function analyzes the function prologue and tries to work
+ out where registers are saved and how long the prologue is.
+ The prologue will consist of the following parts:
+ 1) Optional profiling instrumentation. The old version uses six
+ instructions. We step over this if there is an exact match.
+ nextpc r8
+ mov r9, ra
+ movhi r10, %hiadj(.LP2)
+ addi r10, r10, %lo(.LP2)
+ call mcount
+ mov ra, r9
+ The new version uses two or three instructions (the last of
+ these might get merged in with the STW which saves RA to the
+ stack). We interpret these.
+ mov r8, ra
+ call mcount
+ mov ra, r8
+
+ 2) Optional interrupt entry decision. Again, we step over
+ this if there is an exact match.
+ rdctl et,estatus
+ andi et,et,1
+ beq et,zero, <software_exception>
+ rdctl et,ipending
+ beq et,zero, <software_exception>
+
+ 3) A stack adjustment or stack which, which will be one of:
+ addi sp, sp, -constant
+ or:
+ movi r8, constant
+ sub sp, sp, r8
+ or
+ movhi r8, constant
+ addi r8, r8, constant
+ sub sp, sp, r8
+ or
+ movhi rx, %hiadj(newstack)
+ addhi rx, rx, %lo(newstack)
+ stw sp, constant(rx)
+ mov sp, rx
+
+ 4) An optional stack check, which can take either of these forms:
+ bgeu sp, rx, +8
+ break 3
+ or
+ bltu sp, rx, .Lstack_overflow
+ ...
+ .Lstack_overflow:
+ break 3
+
+ 5) Saving any registers which need to be saved. These will
+ normally just be stored onto the stack:
+ stw rx, constant(sp)
+ but in the large frame case will use r8 as an offset back
+ to the cfa:
+ add r8, r8, sp
+ stw rx, -constant(r8)
+
+ Saving control registers looks slightly different:
+ rdctl rx, ctlN
+ stw rx, constant(sp)
+
+ 6) An optional FP setup, either if the user has requested a
+ frame pointer or if the function calls alloca.
+ This is always:
+ mov fp, sp
+
+ The prologue instructions may be interleaved, and the register
+ saves and FP setup can occur in either order.
+
+ To cope with all this variability we decode all the instructions
+ from the start of the prologue until we hit a branch, call or
+ return. For each of the instructions mentioned in 3, 4 and 5 we
+ handle the limited cases of stores to the stack and operations
+ on constant values.
+ */
+
+typedef struct
+{
+ unsigned int insn;
+ unsigned int mask;
+} wild_insn;
+
+static const wild_insn profiler_insn[] =
+{
+ { 0x0010e03a, 0x00000000 }, // nextpc r8
+ { 0xf813883a, 0x00000000 }, // mov r9,ra
+ { 0x02800034, 0x003FFFC0 }, // movhi r10,257
+ { 0x52800004, 0x003FFFC0 }, // addi r10,r10,-31992
+ { 0x00000000, 0xFFFFFFC0 }, // call <mcount>
+ { 0x483f883a, 0x00000000 } // mov ra,r9
+};
+
+static const wild_insn irqentry_insn[] =
+{
+ { 0x0031307a, 0x00000000 }, // rdctl et,estatus
+ { 0xc600004c, 0x00000000 }, // andi et,et,1
+ { 0xc0000026, 0x003FFFC0 }, // beq et,zero, <software_exception>
+ { 0x0031313a, 0x00000000 }, // rdctl et,ipending
+ { 0xc0000026, 0x003FFFC0 } // beq et,zero, <software_exception>
+};
+
+static void
+nios2_setup_default(struct nios2_unwind_cache *cache)
+{
+ int i;
+
+ for (i = 0; i < NIOS2_NUM_REGS; i++)
+ {
+ /* All registers start off holding their previous values */
+ cache->reg_value[i].reg = i;
+ cache->reg_value[i].offset = 0;
+
+ /* All registers start off not saved */
+ cache->reg_saved[i].basereg = -1;
+ cache->reg_saved[i].addr = 0;
+ }
+}
+
+static int
+nios2_match_sequence(CORE_ADDR start_pc, const wild_insn * sequence, int count)
+{
+ CORE_ADDR pc = start_pc;
+ int i;
+ unsigned int insn;
+
+ for (i = 0 ; i < count ; i++)
+ {
+ insn = read_memory_unsigned_integer (pc, NIOS2_OPCODE_SIZE);
+ if ((insn & ~sequence[i].mask) != sequence[i].insn)
+ return 0;
+
+ pc += NIOS2_OPCODE_SIZE;
+ }
+
+ return 1;
+}
+
+
+CORE_ADDR
+nios2_analyze_prologue (const CORE_ADDR start_pc, const CORE_ADDR current_pc,
+ struct nios2_unwind_cache *cache, struct frame_info *next_frame)
+{
+ /* Maximum lines of prologue to check */
+ /* Note that this number should not be too large, else we can potentially */
+ /* end up iterating through unmapped memory */
+ CORE_ADDR limit_pc = start_pc + 200;
+ int regno;
+
+ /* Does the frame set up the FP register? */
+ int base_reg = 0;
+
+ REG_VALUE * value = cache->reg_value;
+ REG_VALUE temp_value[NIOS2_NUM_REGS];
+
+ int i;
+
+ /* Save the starting PC so we can correct the pc after running */
+ /* through the prolog, using symbol info */
+ CORE_ADDR pc = start_pc;
+
+ /* Is this an exception handler? */
+ int exception_handler = 0;
+
+ /* What was the original value of SP (or fake original value for
+ * functions which switch stacks?
+ */
+ CORE_ADDR frame_high;
+
+ /* Is this the end of the prologue? */
+ int within_prologue = 1;
+
+ CORE_ADDR prologue_end;
+
+ /* Is this the innermost function? */
+ int innermost = (frame_relative_level(next_frame) < 0);
+
+#ifdef DEBUG_PRINT
+ fprintf_unfiltered (gdb_stdlog,
+ "{ nios2_analyze_prologue start=0x%s, current=0x%s ",
+ paddr_nz (start_pc), paddr_nz (current_pc));
+#endif
+
+ /* Set up the default values of the registers. */
+ nios2_setup_default(cache);
+
+ /* If the first few instructions are the profile entry then skip over them. */
+ /* Newer versions of the compiler use more efficient profiling code. */
+ if (nios2_match_sequence(pc, profiler_insn, sizeof(profiler_insn)/sizeof(profiler_insn[0])))
+ pc += sizeof(profiler_insn)/sizeof(profiler_insn[0]) * NIOS2_OPCODE_SIZE;
+
+ /* If the first few are an interrupt entry then skip over them too */
+ if (nios2_match_sequence(pc, irqentry_insn, sizeof(irqentry_insn)/sizeof(irqentry_insn[0])))
+ {
+ pc += sizeof(irqentry_insn)/sizeof(irqentry_insn[0]) * NIOS2_OPCODE_SIZE;
+ exception_handler = 1;
+ }
+
+ prologue_end = start_pc;
+
+ /* Find the prologue instructions. */
+ /* Fortunately we're in 32bit paradise */
+ while (pc < limit_pc && within_prologue)
+ {
+ /* Present instruction. */
+ unsigned int insn;
+
+ int prologue_insn = 0;
+
+ if (pc == current_pc)
+ {
+ /*
+ * When we reach the current PC we must save the current register
+ * state (for the backtrace) but keep analysing because there might
+ * be more to find out (eg. is this an exception handler).
+ */
+ memcpy(temp_value, value, sizeof(temp_value));
+ value = temp_value;
+#ifdef DEBUG_PRINT
+ fprintf_unfiltered (gdb_stdlog, "*");
+#endif
+ }
+
+ insn = read_memory_unsigned_integer (pc, NIOS2_OPCODE_SIZE);
+ pc += NIOS2_OPCODE_SIZE;
+
+#ifdef DEBUG_PRINT
+ fprintf_unfiltered (gdb_stdlog, "[%08X]", insn);
+#endif
+
+ /* The following instructions can appear in the prologue */
+
+ if ((insn & 0x0001FFFF) == 0x0001883A)
+ {
+ /* ADD rc, ra, rb (also used for MOV) */
+
+ int ra = GET_IW_A(insn);
+ int rb = GET_IW_B(insn);
+ int rc = GET_IW_C(insn);
+
+ if (rc == SP_REGNUM && rb == 0 && value[ra].reg == cache->reg_saved[SP_REGNUM].basereg)
+ {
+ /* If the previous value of SP is available somewhere near the new
+ * stack pointer value then this is a stack switch.
+ */
+
+ /* If any registers were saved on the stack before then we can't backtrace
+ * into them now.
+ */
+ for (i = 0 ; i < NIOS2_NUM_REGS ; i++)
+ {
+ if (cache->reg_saved[i].basereg == SP_REGNUM)
+ cache->reg_saved[i].basereg = -1;
+ if (value[i].reg == SP_REGNUM)
+ value[i].reg = -1;
+ }
+
+ /* Create a fake "high water mark" 4 bytes above where SP was stored
+ * and fake up the registers to be consistent with that.
+ */
+ value[SP_REGNUM].reg = SP_REGNUM;
+ value[SP_REGNUM].offset = value[ra].offset - cache->reg_saved[SP_REGNUM].addr - 4;
+
+ cache->reg_saved[SP_REGNUM].basereg = SP_REGNUM;
+ cache->reg_saved[SP_REGNUM].addr = -4;
+ }
+
+ else if (rc != 0)
+ {
+ if (value[rb].reg == 0)
+ value[rc].reg = value[ra].reg;
+ else if (value[ra].reg == 0)
+ value[rc].reg = value[rb].reg;
+ else
+ value[rc].reg = -1;
+
+ value[rc].offset = value[ra].offset + value[rb].offset;
+ }
+ prologue_insn = 1;
+ }
+
+ else if ((insn & 0x0001FFFF) == 0x0001983A)
+ {
+ /* SUB rc, ra, rb */
+
+ int ra = GET_IW_A(insn);
+ int rb = GET_IW_B(insn);
+ int rc = GET_IW_C(insn);
+
+ if (rc != 0)
+ {
+ if (value[rb].reg == 0)
+ value[rc].reg = value[ra].reg;
+ else
+ value[rc].reg = -1;
+
+ value[rc].offset = value[ra].offset - value[rb].offset;
+ }
+ }
+
+ else if ((insn & 0x0000003F) == 0x00000004)
+ {
+ /* ADDI rb, ra, immed (also used for MOVI) */
+ short immed = GET_IW_IMM16(insn);
+ int ra = GET_IW_A(insn);
+ int rb = GET_IW_B(insn);
+
+ if (rb == SP_REGNUM)
+ {
+ /* The first stack adjustment is part of the prologue. Any subsequent
+ stack adjustments are either down to alloca or the epilogue so stop
+ analysing when we hit them. */
+ if (value[rb].offset != 0 || value[ra].reg != SP_REGNUM)
+ break;
+ }
+
+ if (rb != 0)
+ {
+ value[rb].reg = value[ra].reg;
+ value[rb].offset = value[ra].offset + immed;
+ }
+
+ prologue_insn = 1;
+ }
+
+ else if ((insn & 0x0000003F) == 0x00000034)
+ {
+ /* ORHI rb, ra, immed (also used for MOVHI) */
+ unsigned int immed = GET_IW_IMM16(insn);
+ int ra = GET_IW_A(insn);
+ int rb = GET_IW_B(insn);
+
+ if (rb != 0)
+ {
+ value[rb].reg = (value[ra].reg == 0) ? 0 : -1;
+ value[rb].offset = value[ra].offset | (immed << 16);
+ }
+ }
+
+ else if (((insn & IW_OP_MASK) == OP_STW || (insn & IW_OP_MASK) == OP_STWIO))
+ {
+ /* STW rb, immediate(ra) */
+
+ short immed16 = GET_IW_IMM16(insn);
+ int ra = GET_IW_A(insn);
+ int rb = GET_IW_B(insn);
+
+ /* Are we storing the original value of a register? For exception handlers
+ * the value of EA-4 (return address from interrupts etc) is sometimes stored.
+ */
+ int orig = value[rb].reg;
+ if (orig > 0 && (value[rb].offset == 0 || (orig == EA_REGNUM && value[rb].offset == -4)))
+ {
+ /* We are most interested in stores to the stack, but will also take note
+ * of stores to other places as they might be useful later.
+ */
+ if ((value[ra].reg == SP_REGNUM && cache->reg_saved[orig].basereg != SP_REGNUM) ||
+ cache->reg_saved[orig].basereg == -1)
+ {
+ if (pc < current_pc)
+ {
+ /* Save off callee saved registers */
+ cache->reg_saved[orig].basereg = value[ra].reg;
+ cache->reg_saved[orig].addr = value[ra].offset + GET_IW_IMM16(insn);
+ }
+
+ prologue_insn = 1;
+
+ if (orig == EA_REGNUM || orig == ESTATUS_REGNUM)
+ exception_handler = 1;
+ }
+ }
+ }
+
+ else if ((insn & 0xFFC1F83F) == 0x0001303A)
+ {
+ /* RDCTL rC, ctlN */
+ int rc = GET_IW_C(insn);
+ int n = GET_IW_CONTROL_REGNUM(insn);
+
+ if (rc != 0)
+ {
+ value[rc].reg = STATUS_REGNUM + n;
+ value[rc].offset = 0;
+ }
+
+ prologue_insn = 1;
+ }
+
+ else if ((insn & 0x0000003F) == 0 &&
+ value[8].reg == RA_REGNUM && value[8].offset == 0 &&
+ value[SP_REGNUM].reg == SP_REGNUM && value[SP_REGNUM].offset == 0)
+ {
+ /* A CALL instruction. This is treated as a call to mcount if ra
+ * has been stored into r8 beforehand and if it's before the stack adjust.
+ * mcount corrupts r2-r3, r9-r15 & ra
+ */
+ for (i = 2 ; i <= 3 ; i++)
+ value[i].reg = -1;
+ for (i = 9 ; i <= 15 ; i++)
+ value[i].reg = -1;
+ value[RA_REGNUM].reg = -1;
+
+ prologue_insn = 1;
+ }
+
+ else if ((insn & 0xF83FFFFF) == 0xD800012E)
+ {
+ /* BGEU sp, rx, +8
+ * BREAK 3
+ * This instruction sequence is used in stack checking - we can ignore it
+ */
+ unsigned int next_insn = read_memory_unsigned_integer(pc, NIOS2_OPCODE_SIZE);
+
+ if (next_insn != 0x003DA0FA)
+ within_prologue = 0;
+ else
+ pc += NIOS2_OPCODE_SIZE;
+ }
+
+ else if ((insn & 0xF800003F) == 0xD8000036)
+ {
+ /* BLTU sp, rx, .Lstackoverflow
+ * If the location branched to holds a BREAK 3 instruction then this is
+ * also stack overflow detection. We can ignore it.
+ */
+ CORE_ADDR target_pc = pc + ((insn & 0x3FFFC0) >> 6);
+ unsigned int target_insn = read_memory_unsigned_integer(target_pc, NIOS2_OPCODE_SIZE);
+
+ if (target_insn != 0x003DA0FA)
+ within_prologue = 0;
+ }
+
+ /* Any other instructions are allowed to be moved up into the prologue. If we
+ reach a branch, call or return then the prologue is considered over */
+ /* We also consider a second stack adjustment as terminating the prologue (see
+ above) */
+
+ else
+ {
+ switch (GET_IW_OP(insn))
+ {
+ case OP_BEQ:
+ case OP_BGE:
+ case OP_BGEU:
+ case OP_BLT:
+ case OP_BLTU:
+ case OP_BNE:
+ case OP_BR:
+ case OP_CALL:
+ within_prologue = 0;
+ break;
+ case OP_OPX:
+ if (GET_IW_OPX(insn) == OPX_RET ||
+ GET_IW_OPX(insn) == OPX_ERET ||
+ GET_IW_OPX(insn) == OPX_BRET ||
+ GET_IW_OPX(insn) == OPX_CALLR ||
+ GET_IW_OPX(insn) == OPX_JMP)
+ {
+ within_prologue = 0;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (prologue_insn)
+ prologue_end = pc;
+ }
+
+ /* Are we within the function epilogue? If so then we should go back to the
+ original register values */
+ if (innermost && current_pc > start_pc)
+ {
+ /* First check whether the previous instruction was a stack
+ adjustment. */
+ unsigned int insn = read_memory_unsigned_integer (current_pc - NIOS2_OPCODE_SIZE, NIOS2_OPCODE_SIZE);
+
+ if ((insn & 0xFFC0003C) == 0xDEC00004 || /* ADDI sp, sp, */
+ (insn & 0xFFC1FFFF) == 0xDEC1883A || /* ADD sp, sp, */
+ (insn & 0xFFC0003F) == 0xDEC00017) /* LDW sp, constant(sp) */
+ {
+ /* Then check if it's followed by a return or a tail call */
+ insn = read_memory_unsigned_integer (current_pc, NIOS2_OPCODE_SIZE);
+
+ if (insn == 0xF800283A || /* RET */
+ insn == 0xE800083A || /* ERET */
+ (insn & 0x07FFFFFF) == 0x0000683A || /* JMP */
+ (insn & 0xFFC0003F) == 6) /* BR */
+ {
+ /* Go back to default value of the registers */
+ nios2_setup_default(cache);
+ }
+ }
+ }
+
+ /* Exception handlers use a different return address register. */
+ if (exception_handler)
+ cache->return_regnum = EA_REGNUM;
+
+#ifdef DEBUG_PRINT
+ fprintf_unfiltered (gdb_stdlog, "\n-> retreg=%d, ", cache->return_regnum);
+#endif
+
+ if (cache->reg_value[FP_REGNUM].reg == SP_REGNUM)
+ {
+ /* If the FP now holds an offset from the CFA then this is a normal
+ frame which uses the frame pointer. */
+ base_reg = FP_REGNUM;
+ }
+ else if (cache->reg_value[SP_REGNUM].reg == SP_REGNUM)
+ {
+ /* FP doesn't hold an offset from the CFA. If SP still holds an
+ offset from the CFA then we might be in a function which omits
+ the frame pointer, or we might be partway through the prologue.
+ In both cases we can find the CFA using SP. */
+ base_reg = SP_REGNUM;
+ }
+ else
+ {
+ /* Somehow the stack pointer has been corrupted. We can't return. */
+#ifdef DEBUG_PRINT
+ fprintf_unfiltered (gdb_stdlog, "<can't reach cfa> }\n");
+#endif
+ return 0;
+ }
+
+ if (cache->reg_value[base_reg].offset == 0 ||
+ cache->reg_saved[RA_REGNUM].basereg != SP_REGNUM ||
+ cache->reg_saved[cache->return_regnum].basereg != SP_REGNUM)
+ {
+ /*
+ * If the frame didn't adjust the stack, didn't save RA or didn't save
+ * EA in an exception handler then it must either be a leaf function
+ * (doesn't call any other functions) or it can't return. If it has
+ * called another function then it can't be a leaf, so set base == 0
+ * to indicate that we can't backtrace past it.
+ */
+
+ if (!innermost)
+ {
+ /* If it isn't the innermost function then it can't be a leaf, unless
+ * it was interrupted. Check whether RA for this frame is the same
+ * as PC. If so then it probably wan't interrupted.
+ */
+ char buf[8];
+ CORE_ADDR ra;
+
+ frame_unwind_register (next_frame, RA_REGNUM, buf);
+ ra = extract_typed_address (buf, builtin_type_void_func_ptr);
+
+ if (ra == current_pc)
+ {
+#ifdef DEBUG_PRINT
+ fprintf_unfiltered (gdb_stdlog, "<noreturn ADJUST 0x%s, r31@r%d+?>, r%d@r%d+?> }\n",
+ paddr_nz(cache->reg_value[base_reg].offset),
+ cache->reg_saved[RA_REGNUM].basereg,
+ cache->return_regnum, cache->reg_saved[cache->return_regnum].basereg);
+#endif
+ return 0;
+ }
+ }
+ }
+
+ /* Get the value of whichever register we are using for the base. */
+ cache->base = frame_unwind_register_unsigned (next_frame, base_reg);
+
+ /* What was the value of SP at the start of this function (or just
+ * after the stack switch).
+ */
+ frame_high = cache->base - cache->reg_value[base_reg].offset;
+
+ /* Adjust all the saved registers such that they contain addresses
+ instead of offsets. */
+ for (i = 0; i < NIOS2_NUM_REGS; i++)
+ if (cache->reg_saved[i].basereg == SP_REGNUM)
+ {
+ cache->reg_saved[i].basereg = Z_REGNUM;
+ cache->reg_saved[i].addr += frame_high;
+ }
+
+ for (i = 0; i < NIOS2_NUM_REGS; i++)
+ if (cache->reg_saved[i].basereg == GP_REGNUM)
+ {
+ CORE_ADDR gp = frame_unwind_register_unsigned (next_frame, GP_REGNUM);
+
+ for ( ; i < NIOS2_NUM_REGS; i++)
+ if (cache->reg_saved[i].basereg == GP_REGNUM)
+ {
+ cache->reg_saved[i].basereg = Z_REGNUM;
+ cache->reg_saved[i].addr += gp;
+ }
+ }
+
+ /* Work out what the value of SP was on the first instruction of this
+ * function. If we didn't switch stacks then this can be trivially
+ * computed from the base address.
+ */
+ if (cache->reg_saved[SP_REGNUM].basereg == Z_REGNUM)
+ {
+ cache->cfa = read_memory_unsigned_integer(cache->reg_saved[SP_REGNUM].addr, 4);
+ }
+ else
+ cache->cfa = frame_high;
+
+ /* Exception handlers restore ESTATUS into STATUS. */
+ if (exception_handler)
+ {
+ cache->reg_saved[STATUS_REGNUM] = cache->reg_saved[ESTATUS_REGNUM];
+ cache->reg_saved[ESTATUS_REGNUM].basereg = -1;
+ }
+
+#ifdef DEBUG_PRINT
+ fprintf_unfiltered (gdb_stdlog, "cfa=0x%s }\n", paddr_nz(cache->cfa));
+#endif
+
+ return prologue_end;
+}
+
+struct frame_info *
+setup_arbitrary_frame (int argc, CORE_ADDR *argv)
+{
+ if (argc != 2)
+ error ("Nios II frame specifications require two arguments: sp and pc");
+
+ return create_new_frame (argv[0], argv[1]);
+}
+
+#ifdef PORTINGTO61
+/* Should be handled by unwind informations. */
+/* However, doing this manually until we can find */
+/* use the CFA information to examine the stack */
+void
+nios2_frame_init_saved_regs (struct frame_info *fi)
+{
+ CORE_ADDR ip;
+
+ /* Examine the entire prologue. */
+ register int frameless_p = 0;
+
+ /* Has this frame's registers already been initialized? */
+ if (fi->saved_regs)
+ return;
+
+ frame_saved_regs_zalloc (fi);
+
+ ip = get_pc_function_start (fi->pc);
+ nios2_examine (ip, fi, frameless_p);
+}
+#endif
+
+
+/* Given a PC value corresponding to the start of a function, return the PC
+ of the first instruction after the function prologue. */
+
+CORE_ADDR
+nios2_skip_prologue (CORE_ADDR start_pc)
+{
+ CORE_ADDR func_addr, func_end;
+ struct symtab_and_line sal;
+ CORE_ADDR pc_after_prologue;
+
+ /* If we have line debugging information, then the end of the prologue
+ should the first assembly instruction of the first source line. */
+ if (find_pc_partial_function (start_pc, NULL, &func_addr, &func_end))
+ {
+ sal = find_pc_line (func_addr, 0);
+ if (sal.end > 0 && sal.end < func_end)
+ return sal.end;
+ }
+
+ return start_pc;
+}
+
+/* nios2_software_single_step() is called just before we want to resume
+ the inferior, if we want to single-step it but there is no hardware
+ or kernel single-step support (NIOS2 on GNU/Linux for example). We find
+ the target of the coming instruction and breakpoint it.
+
+ single_step is also called just after the inferior stops. If we had
+ set up a simulated single-step, we undo our damage. */
+
+void
+nios2_software_single_step (enum target_signal sig, int insert_breakpoints_p)
+{
+ int ii;
+ unsigned int insn;
+ CORE_ADDR pc;
+ CORE_ADDR breaks[2];
+ int imme;
+
+ if (insert_breakpoints_p)
+ {
+ pc = read_pc ();
+ breaks[0] = pc + 4;
+ breaks[1] = -1;
+ insn = read_memory_unsigned_integer (pc, 4);
+
+ /* Calculate the destination of a branch/jump */
+ switch (GET_IW_OP(insn))
+ {
+ /* I-type branch */
+ case OP_BEQ:
+ case OP_BGE:
+ case OP_BGEU:
+ case OP_BLT:
+ case OP_BLTU:
+ case OP_BNE:
+ imme = (short) GET_IW_IMM16(insn);
+ breaks[1] = pc + 4 + imme;
+ break;
+ case OP_BR:
+ imme = (short) GET_IW_IMM16(insn);
+ breaks[0] = pc + 4 + imme;
+ break;
+ /* J-type branch */
+ case OP_CALL:
+ case OP_JMPI:
+ imme = GET_IW_IMM26(insn);
+ breaks[0] = (pc & 0xf0000000) | (imme * 4);
+ break;
+ /* R-type branch */
+ case OP_OPX:
+ switch (GET_IW_OPX(insn))
+ {
+ case OPX_CALLR:
+ case OPX_JMP:
+ case OPX_RET:
+ imme = read_register (GET_IW_A(insn));
+ breaks[0] = imme;
+ break;
+ }
+ break;
+ }
+
+ /* Don't put two breakpoints on the same address. */
+ if (breaks[1] == breaks[0])
+ breaks[1] = -1;
+
+ for (ii = 0; ii < 2; ++ii)
+ {
+ /* ignore invalid breakpoint. */
+ if (breaks[ii] == -1)
+ continue;
+ insert_single_step_breakpoint (breaks[ii]);
+ }
+ }
+ else
+ remove_single_step_breakpoints ();
+
+}
+
+const unsigned char*
+nios2_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size)
+{
+ /* break encoding: 31->27 26->22 21->17 16->11 10->6 5->0 */
+ /* 00000 00000 0x1e 0x34 00000 0x3a */
+ /* 00000 00000 11110 110100 00000 111010 */
+ /* In bytes: 00000000 00111101 10100000 00111010 */
+ /* 0x0 0x3d 0xa0 0x3a */
+#if 0
+ static unsigned char breakpoint[] = {0x3a, 0xa0, 0x3d, 0x0};
+#else
+ static unsigned char breakpoint[] = {0x7a, 0x68, 0x3b, 0x0}; /* Trap instr. w/imm=0x01 */
+#endif
+ *bp_size = 4;
+ return breakpoint;
+}
+
+
+int
+gdb_print_insn_nios2 (bfd_vma memaddr, disassemble_info *info)
+{
+ if (info->endian == BFD_ENDIAN_BIG)
+ {
+ return print_insn_big_nios2 (memaddr, info);
+ }
+ else
+ {
+ return print_insn_little_nios2 (memaddr, info);
+ }
+}
+
+
+
+/* Adjust the address downward (direction of stack growth) so that it
+ is correctly aligned for a new stack frame. */
+
+/* ??? Big endian issues here? */
+
+static CORE_ADDR
+nios2_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+ return align_down (addr, 4);
+}
+
+
+
+/* We don't convert anything at the moment */
+static int
+nios2_convert_register_p (int regnum, struct type *type)
+{
+ return 0;
+}
+
+static void
+nios2_register_to_value (struct frame_info *frame, int regnum,
+ struct type *type, void *to)
+{
+ get_frame_register (frame, regnum + 0, (char *) to + 0);
+ get_frame_register (frame, regnum + 0, (char *) to + 0);
+}
+
+static void
+nios2_value_to_register (struct frame_info *frame, int regnum,
+ struct type *type, const void *from)
+{
+ put_frame_register (frame, regnum + 0, (const char *) from + 0);
+ put_frame_register (frame, regnum + 0, (const char *) from + 0);
+}
+
+/* Determine, for architecture GDBARCH, how a return value of TYPE
+ should be returned. If it is supposed to be returned in registers,
+ and READBUF is non-zero, read the appropriate value from REGCACHE,
+ and copy it into READBUF. If WRITEBUF is non-zero, write the value
+ from WRITEBUF into REGCACHE. */
+
+static enum return_value_convention
+nios2_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, void *readbuf,
+ const void *writebuf)
+{
+ enum type_code code = TYPE_CODE (type);
+
+ /* FIXME PBrookes add struct return function */
+ if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
+ /*&& !nios2_reg_struct_return_p (gdbarch, type)*/)
+ return RETURN_VALUE_STRUCT_CONVENTION;
+
+
+ if (readbuf)
+ nios2_extract_return_value (type, regcache, readbuf);
+ if (writebuf)
+ nios2_store_return_value (type, regcache);
+
+ return RETURN_VALUE_REGISTER_CONVENTION;
+}
+
+/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
+ dummy frame. The frame ID's base needs to match the TOS value
+ saved by save_dummy_frame_tos() and returned from
+ nios2_push_dummy_call, and the PC needs to match the dummy frame's
+ breakpoint. */
+
+static struct frame_id
+nios2_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ return frame_id_build (frame_unwind_register_unsigned (next_frame, SP_REGNUM),
+ frame_pc_unwind (next_frame));
+}
+
+static CORE_ADDR
+nios2_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ char buf[8];
+
+ frame_unwind_register (next_frame, PC_REGNUM, buf);
+ return extract_typed_address (buf, builtin_type_void_func_ptr);
+}
+
+
+/* Frame base handling. */
+
+struct nios2_unwind_cache *
+nios2_frame_unwind_cache (struct frame_info *next_frame,
+ void **this_prologue_cache)
+{
+ CORE_ADDR current_pc;
+ struct nios2_unwind_cache *cache;
+ int i;
+
+ if (*this_prologue_cache)
+ return *this_prologue_cache;
+
+ cache = FRAME_OBSTACK_ZALLOC (struct nios2_unwind_cache);
+ (*this_prologue_cache) = cache;
+
+ /* Zero all fields. */
+ cache->base = 0;
+ cache->cfa = 0;
+ cache->pc = 0;
+
+ cache->return_regnum = RA_REGNUM;
+
+ nios2_setup_default(cache);
+
+ cache->pc = frame_func_unwind (next_frame);
+ current_pc = frame_pc_unwind (next_frame);
+
+ /* Prologue analysis does the rest... */
+ if (cache->pc != 0)
+ nios2_analyze_prologue (cache->pc, current_pc, cache, next_frame);
+
+ return cache;
+}
+
+static void
+nios2_frame_this_id (struct frame_info *next_frame, void **this_cache,
+ struct frame_id *this_id)
+{
+ struct nios2_unwind_cache *cache =
+ nios2_frame_unwind_cache (next_frame, this_cache);
+
+ /* This marks the outermost frame. */
+ if (cache->base == 0)
+ return;
+
+ (*this_id) = frame_id_build (cache->cfa, cache->pc);
+}
+
+static void
+nios2_frame_prev_register (struct frame_info *next_frame, void **this_cache,
+ int regnum, int *optimizedp,
+ enum lval_type *lvalp, CORE_ADDR *addrp,
+ int *realnump, void *valuep)
+{
+ struct nios2_unwind_cache *cache =
+ nios2_frame_unwind_cache (next_frame, this_cache);
+
+ gdb_assert (regnum >= 0);
+
+ /* The PC of the previous frame is stored in the RA register of
+ the current frame. Frob regnum so that we pull the value from
+ the correct place. */
+ if (regnum == PC_REGNUM)
+ regnum = cache->return_regnum;
+
+ /* If we've worked out where a register is stored then load it from there.
+ */
+ if (regnum < NIOS2_NUM_REGS && cache->reg_saved[regnum].basereg == Z_REGNUM)
+ {
+ *optimizedp = 0;
+ *lvalp = lval_memory;
+ *addrp = cache->reg_saved[regnum].addr;
+ *realnump = -1;
+ if (valuep)
+ {
+ /* Read the value in from memory. */
+ read_memory (*addrp, valuep,
+ register_size (current_gdbarch, regnum));
+ }
+ return;
+ }
+
+ if (regnum == SP_REGNUM && cache->cfa)
+ {
+ *optimizedp = 0;
+ *lvalp = not_lval;
+ *addrp = 0;
+ *realnump = -1;
+ if (valuep)
+ {
+ /* Store the value. */
+ store_unsigned_integer (valuep, 8, cache->cfa);
+ }
+ return;
+ }
+
+ frame_register_unwind (next_frame, regnum,
+ optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+
+
+static const struct frame_unwind nios2_frame_unwind =
+{
+ NORMAL_FRAME,
+ nios2_frame_this_id,
+ nios2_frame_prev_register
+};
+
+static CORE_ADDR
+nios2_frame_base_address (struct frame_info *next_frame, void **this_cache)
+{
+ struct nios2_unwind_cache *info
+ = nios2_frame_unwind_cache (next_frame, this_cache);
+ return info->base;
+}
+
+static const struct frame_base nios2_frame_base =
+{
+ &nios2_frame_unwind,
+ nios2_frame_base_address,
+ nios2_frame_base_address,
+ nios2_frame_base_address
+};
+
+static const struct frame_unwind *
+nios2_frame_sniffer (struct frame_info *next_frame)
+{
+ return &nios2_frame_unwind;
+}
+
+
+static struct gdbarch *
+nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch *gdbarch;
+ int register_bytes, i;
+
+ /* Change the register names based on the current machine type. */
+ if (info.bfd_arch_info->arch != bfd_arch_nios2)
+ return NULL;
+
+ /* None found, create a new architecture from the information
+ provided. We don't have any architecture specific state, so just
+ pass in 0 for the struct gdbarch_tdep parameter. */
+ gdbarch = gdbarch_alloc (&info, NULL);
+
+ /* Data type sizes. */
+ set_gdbarch_ptr_bit (gdbarch, 32);
+ set_gdbarch_addr_bit (gdbarch, 32);
+ set_gdbarch_short_bit (gdbarch, 16);
+ set_gdbarch_int_bit (gdbarch, 32);
+ set_gdbarch_long_bit (gdbarch, 32);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ set_gdbarch_float_bit (gdbarch, 32);
+ set_gdbarch_double_bit (gdbarch, 64);
+
+ switch (info.byte_order)
+ {
+ case BFD_ENDIAN_BIG:
+ set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big);
+ set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_big);
+ break;
+
+ case BFD_ENDIAN_LITTLE:
+ set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
+ set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_little);
+ break;
+
+ default:
+ internal_error (__FILE__, __LINE__,
+ "nios2_gdbarch_init: bad byte ordering");
+ break;
+ }
+
+ /* The register set. */
+ set_gdbarch_num_regs (gdbarch, NIOS2_NUM_REGS);
+ set_gdbarch_sp_regnum (gdbarch, SP_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, PC_REGNUM); /* Pseudo register PC */
+
+ set_gdbarch_register_name (gdbarch, nios2_register_name);
+ /* Length of ordinary registers used in push_word and a few other
+ places. DEPRECATED_REGISTER_RAW_SIZE is the real way to know how
+ big a register is. */
+/* FIXME
+ set_gdbarch_deprecated_register_size (gdbarch, 4);
+ set_gdbarch_deprecated_register_virtual_type (gdbarch,
+ nios2_register_virtual_type);
+*/
+
+ set_gdbarch_register_type (gdbarch, nios2_register_type);
+
+ /* The "default" register numbering scheme for AMD64 is referred to
+ as the "DWARF Register Number Mapping" in the System V psABI.
+ The preferred debugging format for all known Nios II targets is
+ actually DWARF2, and GCC doesn't seem to support DWARF (that is
+ DWARF-1), but we provide the same mapping just in case. This
+ mapping is also used for stabs, which GCC does support. */
+ set_gdbarch_stab_reg_to_regnum (gdbarch, nios2_dwarf_reg_to_regnum);
+ set_gdbarch_dwarf_reg_to_regnum (gdbarch, nios2_dwarf_reg_to_regnum);
+ set_gdbarch_dwarf2_reg_to_regnum (gdbarch, nios2_dwarf_reg_to_regnum);
+
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+
+ /* Call dummy code. */
+ set_gdbarch_frame_align (gdbarch, nios2_frame_align);
+
+ /* Some registers require conversion from raw format to virtual format. */
+/* FIXME
+ set_gdbarch_deprecated_register_convertible (gdbarch, nios2_register_convertible);
+*/
+
+ set_gdbarch_convert_register_p (gdbarch, nios2_convert_register_p);
+ set_gdbarch_register_to_value (gdbarch, nios2_register_to_value);
+ set_gdbarch_value_to_register (gdbarch, nios2_value_to_register);
+
+ set_gdbarch_return_value (gdbarch, nios2_return_value);
+
+ set_gdbarch_skip_prologue (gdbarch, nios2_skip_prologue);
+ set_gdbarch_breakpoint_from_pc (gdbarch, nios2_breakpoint_from_pc);
+ set_gdbarch_software_single_step (gdbarch, nios2_software_single_step);
+
+ set_gdbarch_unwind_dummy_id (gdbarch, nios2_unwind_dummy_id);
+ set_gdbarch_unwind_pc (gdbarch, nios2_unwind_pc);
+
+ /* The dwarf2 unwinder will normally produce the best results if the
+ debug information is available, so register it first. */
+ frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
+
+ /* FIXME: PBrookes - copied from AMD64-TDEP.c (kettenis/20021026):
+ This is ELF-specific. Fine for now, since all supported NIOS II
+ targets are ELF, but that might change in the future. */
+/* FIXME again.. Does not exist anymore...
+ set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
+*/
+
+ frame_unwind_append_sniffer (gdbarch, nios2_frame_sniffer);
+
+ frame_base_set_default (gdbarch, &nios2_frame_base);
+
+ set_gdbarch_print_insn (gdbarch, gdb_print_insn_nios2);
+
+ return gdbarch;
+}
+
+void
+_initialize_nios2_tdep (void)
+{
+ register_gdbarch_init (bfd_arch_nios2, nios2_gdbarch_init);
+
+ int i, offset = 0;
+
+ /* Do not display anything after NIOS2_MAX_REG_DISPLAYED_REGNUM */
+ for (i = 0; i <= NIOS2_MAX_REG_DISPLAYED_REGNUM; i++)
+ {
+ nios2_register_byte_table[i] = offset;
+ offset += nios2_register_info_table[i].size;
+ }
+
+ for (i = NIOS2_MAX_REG_DISPLAYED_REGNUM + 1; i <= NIOS2_NUM_REGS; i++)
+ {
+ nios2_register_byte_table[i] = -1;
+ }
+
+}
diff --git a/gdb/regformats/reg-nios2.dat b/gdb/regformats/reg-nios2.dat
new file mode 100644
index 0000000..77b39a9
--- /dev/null
+++ b/gdb/regformats/reg-nios2.dat
@@ -0,0 +1,46 @@
+name:nios2
+expedite:sp,fp,pc
+32:zero
+32:at
+32:r2
+32:r3
+32:r4
+32:r5
+32:r6
+32:r7
+32:r8
+32:r9
+32:r10
+32:r11
+32:r12
+32:r13
+32:r14
+32:r15
+32:r16
+32:r17
+32:r18
+32:r19
+32:r20
+32:r21
+32:r22
+32:r23
+32:et
+32:bt
+32:gp
+32:sp
+32:fp
+32:ea
+32:ba
+32:ra
+32:pc
+32:status
+32:estatus
+32:bstatus
+32:ienable
+32:ipending
+32:cpuid
+32:ctl6
+32:ctl7
+32:pteaddr
+32:tlbacc
+32:tlbmisc
diff --git a/gdb/testsuite/config/nios2-iss.exp b/gdb/testsuite/config/nios2-iss.exp
new file mode 100644
index 0000000..624f831
--- /dev/null
+++ b/gdb/testsuite/config/nios2-iss.exp
@@ -0,0 +1,233 @@
+# Test framework for GDB (remote protocol) using a "gdbserver",
+# ie. a debug agent running as a native process on the same or
+# a different host.
+
+# Copyright 2000, 2002 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder. (msnyder@redhat.com)
+
+#
+# This module to be used for testing gdb with a "gdbserver"
+# built either from libremote or from gdb/gdbserver.
+#
+
+# Load the basic testing library, and the remote stuff.
+load_lib ../config/monitor.exp
+
+#
+# To be addressed or set in your baseboard config file:
+#
+# set_board_info gdb_protocol "remote"
+# Unles you have a gdbserver that uses a different protocol...
+#
+# set_board_info use_gdb_stub 1
+# This tells the rest of the test suite not to do things
+# like "run" which don't work well on remote targets.
+#
+# set_board_info gdb,do_reload_on_run 1
+# Unles you have a gdbserver that can handle multiple sessions.
+#
+# set_board_info noargs 1
+# At present there is no provision in the remote protocol
+# for passing arguments. This test framework does not
+# address the issue, so it's best to set this variable
+# in your baseboard configuration file.
+# FIXME: there's no reason why the test harness couldn't
+# pass commandline args when it spawns gdbserver.
+#
+# set_board_info gdb,noinferiorio 1
+# Neither the traditional gdbserver nor the one in libremote
+# can presently capture stdout and relay it to GDB via the
+# 'O' packet. This means that tests involving printf will
+# fail unles you set this varibale in your baseboard
+# configuration file.
+#
+# set_board_info gdb,no_hardware_watchpoints 1
+# Unles you have a gdbserver that supports hardware watchpoints.
+# FIXME: gdb should detect if the target doesn't support them,
+# and fall back to using software watchpoints.
+#
+# set_board_info gdb_server_prog
+# This will be the path to the gdbserver program you want to test.
+# Defaults to "gdbserver".
+#
+# set_board_info sockethost
+# The name of the host computer whose socket is being used.
+# Defaults to "localhost". Note: old gdbserver requires
+# that you define this, but libremote/gdbserver does not.
+#
+# set_board_info socketport
+# Port id to use for socket connection. If not set explicitly,
+# it will start at "9996" and increment for each use.
+#
+
+
+
+#
+# gdb_load -- load a file into the debugger.
+# return a -1 if anything goes wrong.
+#
+
+global server_exec;
+global portnum;
+set portnum "9996";
+
+proc gdb_load { arg } {
+ global host_exec;
+ global server_exec;
+ global portnum;
+ global verbose;
+ global gdb_prompt;
+
+ regsub "/cygdrive/c" $arg "c:" arg
+ regsub "/cygdrive/d" $arg "d:" arg
+ regsub "/cygdrive/e" $arg "e:" arg
+ regsub "/cygdrive/q" $arg "q:" arg
+ regsub "/cygdrive/r" $arg "r:" arg
+
+ # Always kill and restart quest (or try to before loading)
+ slay quest
+ slay gdb
+
+ # Port id -- either specified in baseboard file, or managed here.
+ if [target_info exists gdb,socketport] {
+ set portnum [target_info gdb,socketport];
+ } else {
+ # Bump the port number to avoid conflicts with hung ports.
+ incr portnum;
+ }
+
+ verbose "gdb_load : portnum = $portnum arg = $arg"
+ # Extract the local and remote host ids from the target board struct.
+
+ if [target_info exists sockethost] {
+ set debughost [target_info sockethost];
+ } else {
+ set debughost "localhost:";
+ }
+ # Extract the protocol
+ if [target_info exists gdb_protocol] {
+ set protocol [target_info gdb_protocol];
+ } else {
+ set protocol "remote";
+ }
+
+ # Extract the name of the gdbserver, if known (default 'gdbserver').
+ if [target_info exists gdb_server_prog] {
+ set gdbserver [target_info gdb_server_prog];
+ } else {
+ set gdbserver "gdbserver";
+ }
+
+ verbose "gdbserver is set to $gdbserver"
+ # Extract the socket hostname
+ if [target_info exists sockethost] {
+ set sockethost [target_info sockethost];
+ } else {
+ set sockethost ""
+ }
+
+ # Export the host:port pair.
+ set gdbport $debughost$portnum;
+ verbose "gdbport is now $gdbport"
+ # Remember new exec file.
+ if { $arg == "" } {
+ if { ! [info exists host_exec] } {
+ send_gdb "info files\n";
+ gdb_expect 30 {
+ -re "Symbols from \"(\[^\"\]+)\"" {
+ set host_exec $expect_out(1,string);
+ exp_continue;
+ }
+ -re "Local exec file:\[\r\n\]+\[ \t\]*`(\[^'\]+)'," {
+ set host_exec $expect_out(1,string);
+ exp_continue;
+ }
+ -re "$gdb_prompt $" { }
+ }
+ }
+ } else {
+ set host_exec $arg
+ if [info exists server_exec] { unset server_exec }
+ }
+
+ # Fire off the debug agent
+ if [target_info exists gdb_server_args] {
+ # This flavour of gdbserver takes as arguments those specified
+ # in the board configuration file
+ set custom_args [target_info gdb_server_args];
+ set launch_return [eval remote_spawn host \{ $gdbserver $custom_args \} $arg ]
+ verbose "spawned $gdbserver $custom_args $arg with return code $launch_return"
+ } else {
+ # This flavour of gdbserver takes as arguments the port information
+ # and the name of the executable file to be debugged.
+ set server_spawn_id [remote_spawn target\
+ "$gdbserver $sockethost$portnum "]
+ verbose "remote_spawn $gdbserver $sockethost$portnum"
+ }
+
+ # We can't call close, because if gdbserver is local then that means
+ # that it will get a SIGHUP.
+ ## close -i $server_spawn_id
+ #wait -nowait -i $server_spawn_id
+
+ # Give it a little time to establish
+ sleep 1
+
+ # tell gdb what file we are debugging
+ if { $arg != "" } {
+ if [gdb_file_cmd $arg] {
+ return -1;
+ }
+ }
+ verbose "gdb_file_cmd has been called with $arg"
+
+ # attach to the "serial port"
+ gdb_target_cmd $protocol $gdbport;
+
+ # do the real load if needed
+ if [target_info exists gdb_server_do_load] {
+ send_gdb "load\n"
+ set timeout 2400
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ if $verbose>1 then {
+ send_user "Loaded $arg into $GDB\n"
+ }
+ set timeout 30
+ verbose "Timeout is now $timeout seconds" 2
+ return 1
+ }
+ -re "$gdb_prompt $" {
+ if $verbose>1 then {
+ perror "GDB couldn't load."
+ }
+ }
+ timeout {
+ if $verbose>1 then {
+ perror "Timed out trying to load $arg."
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/include/dis-asm.h b/include/dis-asm.h
index af48e85..e3d84ab 100644
--- a/include/dis-asm.h
+++ b/include/dis-asm.h
@@ -280,6 +280,8 @@ extern int print_insn_xtensa (bfd_vma, disassemble_info *);
extern int print_insn_z80 (bfd_vma, disassemble_info *);
extern int print_insn_z8001 (bfd_vma, disassemble_info *);
extern int print_insn_z8002 (bfd_vma, disassemble_info *);
+extern int print_insn_little_nios2 (bfd_vma, disassemble_info *);
+extern int print_insn_big_nios2 (bfd_vma, disassemble_info *);
extern disassembler_ftype arc_get_disassembler (void *);
extern disassembler_ftype cris_get_disassembler (bfd *);
diff --git a/include/elf/nios2.h b/include/elf/nios2.h
new file mode 100644
index 0000000..ef810c5
--- /dev/null
+++ b/include/elf/nios2.h
@@ -0,0 +1,65 @@
+/* Altera New Jersey ELF support for BFD
+
+ Copyright (C) 2003
+ by Nigel Gray (ngray@altera.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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file holds definitions specific to the Altera New Jersey ELF ABI. Note
+ that most of this is not actually implemented by BFD. */
+
+#ifndef _ELF_NIOS2_H
+#define _ELF_NIOS2_H
+
+#include "elf/reloc-macros.h"
+
+/* the order of these numbers must match the order in
+ the elf_nios2_howto_table_rel table for the lookup
+ function to work properly */
+
+START_RELOC_NUMBERS (elf_nios2_reloc_type)
+ RELOC_NUMBER (R_NIOS2_NONE, 0)
+ RELOC_NUMBER (R_NIOS2_S16, 1)
+ RELOC_NUMBER (R_NIOS2_U16, 2)
+ RELOC_NUMBER (R_NIOS2_PCREL16, 3)
+ RELOC_NUMBER (R_NIOS2_CALL26, 4)
+ RELOC_NUMBER (R_NIOS2_IMM5, 5)
+ RELOC_NUMBER (R_NIOS2_CACHE_OPX, 6)
+ RELOC_NUMBER (R_NIOS2_IMM6, 7)
+ RELOC_NUMBER (R_NIOS2_IMM8, 8)
+ RELOC_NUMBER (R_NIOS2_HI16, 9)
+ RELOC_NUMBER (R_NIOS2_LO16, 10)
+ RELOC_NUMBER (R_NIOS2_HIADJ16, 11)
+ RELOC_NUMBER (R_NIOS2_BFD_RELOC_32, 12)
+ RELOC_NUMBER (R_NIOS2_BFD_RELOC_16, 13)
+ RELOC_NUMBER (R_NIOS2_BFD_RELOC_8, 14)
+ RELOC_NUMBER (R_NIOS2_GPREL, 15)
+ RELOC_NUMBER (R_NIOS2_GNU_VTINHERIT, 16)
+ RELOC_NUMBER (R_NIOS2_GNU_VTENTRY, 17)
+ RELOC_NUMBER (R_NIOS2_UJMP, 18)
+ RELOC_NUMBER (R_NIOS2_CJMP, 19)
+ RELOC_NUMBER (R_NIOS2_CALLR, 20)
+ RELOC_NUMBER (R_NIOS2_ALIGN, 21)
+ RELOC_NUMBER (R_NIOS2_ILLEGAL, 22)
+END_RELOC_NUMBERS (R_NIOS2_maxext)
+
+/* Processor specific section flags */
+
+/* This is used to mark gp-relative sections */
+#define SHF_NIOS2_GPREL 0x10000000
+
+#endif //_ELF_NIOS2_H
diff --git a/include/opcode/nios2-isa.h b/include/opcode/nios2-isa.h
new file mode 100644
index 0000000..0023880
--- /dev/null
+++ b/include/opcode/nios2-isa.h
@@ -0,0 +1,1860 @@
+/*
+ * This file defines Nios II instruction set constants.
+ * To include it in assembly code (.S file), define ALT_ASM_SRC
+ * before including this file.
+ *
+ * This file is automatically generated by gen_isa.pl - do not edit
+ */
+
+#ifndef _NIOS2_ISA_H_
+#define _NIOS2_ISA_H_
+
+/* OP instruction opcode values (index is OP field) */
+#define NUM_OP_INSTS 64
+
+#ifndef ALT_ASM_SRC
+extern const char* op_names[NUM_OP_INSTS];
+#endif /* ALT_ASM_SRC */
+
+/* OPX instruction opcode values (index is OPX field) */
+#define NUM_OPX_INSTS 64
+
+#ifndef ALT_ASM_SRC
+extern const char* opx_names[NUM_OPX_INSTS];
+#endif /* ALT_ASM_SRC */
+
+/* Constants for instruction fields and ISA */
+#define CPU_RESET_EXC_ID 1
+#define DIV_ERROR_EXC_ID 9
+#define DTLB_MISS_EXC_ID 15
+#define DTLB_PERM_EXC_ID 16
+#define FAST_INTR_EXC_ID 3
+#define HBREAK_EXC_ID 0
+#define ITLB_MISS_EXC_ID 13
+#define ITLB_PERM_EXC_ID 14
+#define MISALIGNED_DATA_ADDR_EXC_ID 7
+#define MISALIGNED_TARGET_PC_EXC_ID 8
+#define NMI_EXC_ID 2
+#define NORM_INTR_EXC_ID 4
+#define SBREAK_EXC_ID 6
+#define SLAVE_DATA_ACCESS_ERROR_EXC_ID 18
+#define SLAVE_INST_ACCESS_ERROR_EXC_ID 17
+#define SUPERVISOR_DATA_ADDR_EXC_ID 12
+#define SUPERVISOR_INST_ADDR_EXC_ID 10
+#define SUPERVISOR_INST_EXC_ID 11
+#define TRAP_EXC_ID 5
+#define AT_REGNUM 1
+#define BRETADDR_REGNUM 30
+#define BSTATUS_REG_LSB 2
+#define BSTATUS_REG_MMU_LSB 0
+#define BSTATUS_REG_MMU_MSB 2
+#define BSTATUS_REG_MMU_SZ 3
+#define BSTATUS_REG_MMU_MASK 0x7
+#define BSTATUS_REG_NO_MMU_LSB 0
+#define BSTATUS_REG_NO_MMU_MSB 0
+#define BSTATUS_REG_NO_MMU_SZ 1
+#define BSTATUS_REG_NO_MMU_MASK 0x1
+#define BSTATUS_REG_REGNUM 2
+#define BSTATUS_REG_SZ 3
+#define BSTATUS_REG_MASK 0x7
+#define BT_REGNUM 25
+#define CACHE_MAX_BYTES 65536
+#define CACHE_MAX_LINE_BYTES 32
+#define CACHE_MIN_LINE_BYTES 4
+#define COMPARE_OP_EQ 0x0
+#define COMPARE_OP_GE 0x1
+#define COMPARE_OP_LSB 3
+#define COMPARE_OP_LT 0x2
+#define COMPARE_OP_MSB 4
+#define COMPARE_OP_NE 0x3
+#define COMPARE_OP_SZ 2
+#define COMPARE_OP_MASK 0x3
+#define CPUID_REG_LSB 0
+#define CPUID_REG_MSB 31
+#define CPUID_REG_REGNUM 5
+#define CPUID_REG_SZ 32
+#define CPUID_REG_MASK 0xffffffff
+#define DATAPATH_LOG2_SZ 5
+#define DATAPATH_LOG2_MASK 0x1f
+#define DATAPATH_LSB 0
+#define DATAPATH_MSB 31
+#define DATAPATH_SZ 32
+#define DATAPATH_MASK 0xffffffff
+#define EMPTY_CRST_IW 127034
+#define EMPTY_HBREAK_IW 4040762
+#define EMPTY_INTR_IW 3926074
+#define EMPTY_NOP_IW 100410
+#define EMPTY_RET_IW 4160759866
+#define ERETADDR_REGNUM 29
+#define ESTATUS_REG_LSB 0
+#define ESTATUS_REG_MMU_LSB 0
+#define ESTATUS_REG_MMU_MSB 2
+#define ESTATUS_REG_MMU_SZ 3
+#define ESTATUS_REG_MMU_MASK 0x7
+#define ESTATUS_REG_MSB 2
+#define ESTATUS_REG_NO_MMU_LSB 0
+#define ESTATUS_REG_NO_MMU_MSB 0
+#define ESTATUS_REG_NO_MMU_SZ 1
+#define ESTATUS_REG_NO_MMU_MASK 0x1
+#define ESTATUS_REG_REGNUM 1
+#define ESTATUS_REG_SZ 3
+#define ESTATUS_REG_MASK 0x7
+#define ET_REGNUM 24
+#define EXCEPTION_REG_LSB 0
+#define EXCEPTION_REG_MEA_LSB 0
+#define EXCEPTION_REG_MEA_MSB 0
+#define EXCEPTION_REG_MEA_SZ 1
+#define EXCEPTION_REG_MEA_MASK 0x1
+#define EXCEPTION_REG_MEE_LSB 1
+#define EXCEPTION_REG_MEE_MSB 1
+#define EXCEPTION_REG_MEE_SZ 1
+#define EXCEPTION_REG_MEE_MASK 0x1
+#define EXCEPTION_REG_MSB 1
+#define EXCEPTION_REG_REGNUM 7
+#define EXCEPTION_REG_SZ 2
+#define EXCEPTION_REG_MASK 0x3
+#define FP_REGNUM 28
+#define FSTATUS_REG_REGNUM 11
+#define GP_REGNUM 26
+#define IENABLE_REG_LSB 0
+#define IENABLE_REG_MSB 31
+#define IENABLE_REG_REGNUM 3
+#define IENABLE_REG_SZ 32
+#define IENABLE_REG_MASK 0xffffffff
+#define IPENDING_REG_LSB 0
+#define IPENDING_REG_MSB 31
+#define IPENDING_REG_REGNUM 4
+#define IPENDING_REG_SZ 32
+#define IPENDING_REG_MASK 0xffffffff
+#define IW_A_LSB 27
+#define IW_A_MSB 31
+#define IW_A_SZ 5
+#define IW_A_MASK 0x1f
+#define IW_B_LSB 22
+#define IW_B_MSB 26
+#define IW_B_SZ 5
+#define IW_B_MASK 0x1f
+#define IW_C_LSB 17
+#define IW_C_MSB 21
+#define IW_C_SZ 5
+#define IW_C_MASK 0x1f
+#define IW_CONTROL_REGNUM_BASE 0
+#define IW_CONTROL_REGNUM_LSB 6
+#define IW_CONTROL_REGNUM_MSB 9
+#define IW_CONTROL_REGNUM_SZ 4
+#define IW_CONTROL_REGNUM_MASK 0xf
+#define IW_CUSTOM_N_LSB 6
+#define IW_CUSTOM_N_MSB 13
+#define IW_CUSTOM_N_SZ 8
+#define IW_CUSTOM_N_MASK 0xff
+#define IW_CUSTOM_READRA_LSB 16
+#define IW_CUSTOM_READRA_MSB 16
+#define IW_CUSTOM_READRA_SZ 1
+#define IW_CUSTOM_READRA_MASK 0x1
+#define IW_CUSTOM_READRB_LSB 15
+#define IW_CUSTOM_READRB_MSB 15
+#define IW_CUSTOM_READRB_SZ 1
+#define IW_CUSTOM_READRB_MASK 0x1
+#define IW_CUSTOM_WRITERC_LSB 14
+#define IW_CUSTOM_WRITERC_MSB 14
+#define IW_CUSTOM_WRITERC_SZ 1
+#define IW_CUSTOM_WRITERC_MASK 0x1
+#define IW_IMM16_LSB 6
+#define IW_IMM16_MSB 21
+#define IW_IMM16_SZ 16
+#define IW_IMM16_MASK 0xffff
+#define IW_IMM26_LSB 6
+#define IW_IMM26_MSB 31
+#define IW_IMM26_SZ 26
+#define IW_IMM26_MASK 0x3ffffff
+#define IW_MEMSZ_BYTE 0x0
+#define IW_MEMSZ_HWORD 0x1
+#define IW_MEMSZ_LSB 3
+#define IW_MEMSZ_MSB 4
+#define IW_MEMSZ_SZ 2
+#define IW_MEMSZ_MASK 0x3
+#define IW_MEMSZ_WORD 0x2
+#define IW_MEMSZ_WORD_MSB 0x1
+#define IW_OP_LSB 0
+#define IW_OP_MSB 5
+#define IW_OP_SZ 6
+#define IW_OP_MASK 0x3f
+#define IW_OPX_LSB 11
+#define IW_OPX_MSB 16
+#define IW_OPX_SZ 6
+#define IW_OPX_MASK 0x3f
+#define IW_SHIFT_IMM5_LSB 6
+#define IW_SHIFT_IMM5_MSB 10
+#define IW_SHIFT_IMM5_SZ 5
+#define IW_SHIFT_IMM5_MASK 0x1f
+#define IW_SZ 32
+#define IW_MASK 0xffffffff
+#define IW_TRAP_BREAK_IMM5_LSB 6
+#define IW_TRAP_BREAK_IMM5_MSB 10
+#define IW_TRAP_BREAK_IMM5_SZ 5
+#define IW_TRAP_BREAK_IMM5_MASK 0x1f
+#define JMP_CALLR_VS_RET_IS_RET 0
+#define JMP_CALLR_VS_RET_OPX_BIT 3
+#define LOGIC_OP_AND 0x1
+#define LOGIC_OP_LSB 3
+#define LOGIC_OP_MSB 4
+#define LOGIC_OP_NOR 0x0
+#define LOGIC_OP_OR 0x2
+#define LOGIC_OP_SZ 2
+#define LOGIC_OP_MASK 0x3
+#define LOGIC_OP_XOR 0x3
+#define MMU_ADDR_BYPASS_TLB 0x3
+#define MMU_ADDR_BYPASS_TLB_CACHEABLE 0x0
+#define MMU_ADDR_BYPASS_TLB_CACHEABLE_LSB 29
+#define MMU_ADDR_BYPASS_TLB_CACHEABLE_MSB 29
+#define MMU_ADDR_BYPASS_TLB_CACHEABLE_SZ 1
+#define MMU_ADDR_BYPASS_TLB_CACHEABLE_MASK 0x1
+#define MMU_ADDR_BYPASS_TLB_LSB 30
+#define MMU_ADDR_BYPASS_TLB_MSB 31
+#define MMU_ADDR_BYPASS_TLB_PADDR_LSB 0
+#define MMU_ADDR_BYPASS_TLB_PADDR_MSB 28
+#define MMU_ADDR_BYPASS_TLB_PADDR_SZ 29
+#define MMU_ADDR_BYPASS_TLB_PADDR_MASK 0x1fffffff
+#define MMU_ADDR_BYPASS_TLB_SZ 2
+#define MMU_ADDR_BYPASS_TLB_MASK 0x3
+#define MMU_ADDR_IO_REGION 0x7
+#define MMU_ADDR_IO_REGION_LSB 29
+#define MMU_ADDR_IO_REGION_MSB 31
+#define MMU_ADDR_IO_REGION_SZ 3
+#define MMU_ADDR_IO_REGION_MASK 0x7
+#define MMU_ADDR_IO_REGION_VPN 0xe0000
+#define MMU_ADDR_KERNEL_MMU_REGION 0x2
+#define MMU_ADDR_KERNEL_MMU_REGION_LSB 30
+#define MMU_ADDR_KERNEL_MMU_REGION_MSB 31
+#define MMU_ADDR_KERNEL_MMU_REGION_SZ 2
+#define MMU_ADDR_KERNEL_MMU_REGION_MASK 0x3
+#define MMU_ADDR_KERNEL_REGION 0x6
+#define MMU_ADDR_KERNEL_REGION_INT 6
+#define MMU_ADDR_KERNEL_REGION_LSB 29
+#define MMU_ADDR_KERNEL_REGION_MSB 31
+#define MMU_ADDR_KERNEL_REGION_SZ 3
+#define MMU_ADDR_KERNEL_REGION_MASK 0x7
+#define MMU_ADDR_PAGE_OFFSET_LSB 0
+#define MMU_ADDR_PAGE_OFFSET_MSB 11
+#define MMU_ADDR_PAGE_OFFSET_SZ 12
+#define MMU_ADDR_PAGE_OFFSET_MASK 0xfff
+#define MMU_ADDR_PFN_LSB 12
+#define MMU_ADDR_PFN_MSB 31
+#define MMU_ADDR_PFN_SZ 20
+#define MMU_ADDR_PFN_MASK 0xfffff
+#define MMU_ADDR_USER_REGION 0x0
+#define MMU_ADDR_USER_REGION_LSB 31
+#define MMU_ADDR_USER_REGION_MSB 31
+#define MMU_ADDR_USER_REGION_SZ 1
+#define MMU_ADDR_USER_REGION_MASK 0x1
+#define MMU_ADDR_VPN_LSB 12
+#define MMU_ADDR_VPN_MSB 31
+#define MMU_ADDR_VPN_SZ 20
+#define MMU_ADDR_VPN_MASK 0xfffff
+#define PTEADDR_REG_LSB 0
+#define PTEADDR_REG_MSB 31
+#define PTEADDR_REG_PTBASE_LSB 22
+#define PTEADDR_REG_PTBASE_MSB 31
+#define PTEADDR_REG_PTBASE_SZ 10
+#define PTEADDR_REG_PTBASE_MASK 0x3ff
+#define PTEADDR_REG_REGNUM 8
+#define PTEADDR_REG_RSV_LSB 0
+#define PTEADDR_REG_RSV_MSB 1
+#define PTEADDR_REG_RSV_SZ 2
+#define PTEADDR_REG_RSV_MASK 0x3
+#define PTEADDR_REG_SZ 32
+#define PTEADDR_REG_MASK 0xffffffff
+#define PTEADDR_REG_VPN_LSB 2
+#define PTEADDR_REG_VPN_MSB 21
+#define PTEADDR_REG_VPN_SZ 20
+#define PTEADDR_REG_VPN_MASK 0xfffff
+#define REGNUM_SZ 5
+#define REGNUM_MASK 0x1f
+#define RETADDR_REGNUM 31
+#define RF_ADDR_SZ 5
+#define RF_ADDR_MASK 0x1f
+#define RF_NUM_REG 32
+#define SIM_REG_LSB 0
+#define SIM_REG_MSB 3
+#define SIM_REG_PERF_CNT_CLR_LSB 2
+#define SIM_REG_PERF_CNT_CLR_MSB 2
+#define SIM_REG_PERF_CNT_CLR_SZ 1
+#define SIM_REG_PERF_CNT_CLR_MASK 0x1
+#define SIM_REG_PERF_CNT_EN_LSB 1
+#define SIM_REG_PERF_CNT_EN_MSB 1
+#define SIM_REG_PERF_CNT_EN_SZ 1
+#define SIM_REG_PERF_CNT_EN_MASK 0x1
+#define SIM_REG_REGNUM 6
+#define SIM_REG_SHOW_DTLB_LSB 4
+#define SIM_REG_SHOW_DTLB_MSB 4
+#define SIM_REG_SHOW_DTLB_SZ 1
+#define SIM_REG_SHOW_DTLB_MASK 0x1
+#define SIM_REG_SHOW_ITLB_LSB 3
+#define SIM_REG_SHOW_ITLB_MSB 3
+#define SIM_REG_SHOW_ITLB_SZ 1
+#define SIM_REG_SHOW_ITLB_MASK 0x1
+#define SIM_REG_SHOW_MMU_REGS_LSB 5
+#define SIM_REG_SHOW_MMU_REGS_MSB 5
+#define SIM_REG_SHOW_MMU_REGS_SZ 1
+#define SIM_REG_SHOW_MMU_REGS_MASK 0x1
+#define SIM_REG_STOP_LSB 0
+#define SIM_REG_STOP_MSB 0
+#define SIM_REG_STOP_SZ 1
+#define SIM_REG_STOP_MASK 0x1
+#define SIM_REG_SZ 4
+#define SIM_REG_MASK 0xf
+#define SP_REGNUM 27
+#define STATUS_REG_EH_LSB 2
+#define STATUS_REG_EH_MSB 2
+#define STATUS_REG_EH_SZ 1
+#define STATUS_REG_EH_MASK 0x1
+#define STATUS_REG_LSB 0
+#define STATUS_REG_MMU_LSB 0
+#define STATUS_REG_MMU_MSB 2
+#define STATUS_REG_MMU_RSV_LSB 3
+#define STATUS_REG_MMU_RSV_MSB 31
+#define STATUS_REG_MMU_RSV_SZ 29
+#define STATUS_REG_MMU_RSV_MASK 0x1fffffff
+#define STATUS_REG_MMU_SZ 3
+#define STATUS_REG_MMU_MASK 0x7
+#define STATUS_REG_MSB 2
+#define STATUS_REG_NO_MMU_LSB 0
+#define STATUS_REG_NO_MMU_MSB 0
+#define STATUS_REG_NO_MMU_RSV_LSB 1
+#define STATUS_REG_NO_MMU_RSV_MSB 31
+#define STATUS_REG_NO_MMU_RSV_SZ 31
+#define STATUS_REG_NO_MMU_RSV_MASK 0x7fffffff
+#define STATUS_REG_NO_MMU_SZ 1
+#define STATUS_REG_NO_MMU_MASK 0x1
+#define STATUS_REG_PIE_LSB 0
+#define STATUS_REG_PIE_MSB 0
+#define STATUS_REG_PIE_SZ 1
+#define STATUS_REG_PIE_MASK 0x1
+#define STATUS_REG_REGNUM 0
+#define STATUS_REG_SZ 3
+#define STATUS_REG_MASK 0x7
+#define STATUS_REG_U_LSB 1
+#define STATUS_REG_U_MSB 1
+#define STATUS_REG_U_SZ 1
+#define STATUS_REG_U_MASK 0x1
+#define TLB_MAX_ENTRIES 1024
+#define TLB_MAX_LINES 512
+#define TLB_MAX_PID_SZ 14
+#define TLB_MAX_PID_MASK 0x3fff
+#define TLB_MAX_PTR_SZ 10
+#define TLB_MAX_PTR_MASK 0x3ff
+#define TLB_MAX_WAYS 8
+#define TLB_MIN_PID_SZ 1
+#define TLB_MIN_PID_MASK 0x1
+#define TLB_MIN_PTR_SZ 7
+#define TLB_MIN_PTR_MASK 0x7f
+#define TLB_MIN_WAYS 2
+#define TLBACC_REG_C_LSB 24
+#define TLBACC_REG_C_MSB 24
+#define TLBACC_REG_C_SZ 1
+#define TLBACC_REG_C_MASK 0x1
+#define TLBACC_REG_G_LSB 20
+#define TLBACC_REG_G_MSB 20
+#define TLBACC_REG_G_SZ 1
+#define TLBACC_REG_G_MASK 0x1
+#define TLBACC_REG_IG_LSB 25
+#define TLBACC_REG_IG_MSB 31
+#define TLBACC_REG_IG_SZ 7
+#define TLBACC_REG_IG_MASK 0x7f
+#define TLBACC_REG_LSB 0
+#define TLBACC_REG_MSB 24
+#define TLBACC_REG_PFN_LSB 0
+#define TLBACC_REG_PFN_MSB 19
+#define TLBACC_REG_PFN_SZ 20
+#define TLBACC_REG_PFN_MASK 0xfffff
+#define TLBACC_REG_R_LSB 23
+#define TLBACC_REG_R_MSB 23
+#define TLBACC_REG_R_SZ 1
+#define TLBACC_REG_R_MASK 0x1
+#define TLBACC_REG_REGNUM 9
+#define TLBACC_REG_SZ 25
+#define TLBACC_REG_MASK 0x1ffffff
+#define TLBACC_REG_W_LSB 22
+#define TLBACC_REG_W_MSB 22
+#define TLBACC_REG_W_SZ 1
+#define TLBACC_REG_W_MASK 0x1
+#define TLBACC_REG_X_LSB 21
+#define TLBACC_REG_X_MSB 21
+#define TLBACC_REG_X_SZ 1
+#define TLBACC_REG_X_MASK 0x1
+#define TLBMISC_REG_BAD_LSB 2
+#define TLBMISC_REG_BAD_MSB 2
+#define TLBMISC_REG_BAD_SZ 1
+#define TLBMISC_REG_BAD_MASK 0x1
+#define TLBMISC_REG_D_LSB 0
+#define TLBMISC_REG_D_MSB 0
+#define TLBMISC_REG_D_SZ 1
+#define TLBMISC_REG_D_MASK 0x1
+#define TLBMISC_REG_DBL_LSB 3
+#define TLBMISC_REG_DBL_MSB 3
+#define TLBMISC_REG_DBL_SZ 1
+#define TLBMISC_REG_DBL_MASK 0x1
+#define TLBMISC_REG_LSB 0
+#define TLBMISC_REG_MSB 23
+#define TLBMISC_REG_PERM_LSB 1
+#define TLBMISC_REG_PERM_MSB 1
+#define TLBMISC_REG_PERM_SZ 1
+#define TLBMISC_REG_PERM_MASK 0x1
+#define TLBMISC_REG_PID_LSB 4
+#define TLBMISC_REG_PID_MSB 17
+#define TLBMISC_REG_PID_SZ 14
+#define TLBMISC_REG_PID_MASK 0x3fff
+#define TLBMISC_REG_RD_LSB 24
+#define TLBMISC_REG_RD_MSB 24
+#define TLBMISC_REG_RD_SZ 1
+#define TLBMISC_REG_RD_MASK 0x1
+#define TLBMISC_REG_REGNUM 10
+#define TLBMISC_REG_RSV0_LSB 18
+#define TLBMISC_REG_RSV0_MSB 19
+#define TLBMISC_REG_RSV0_SZ 2
+#define TLBMISC_REG_RSV0_MASK 0x3
+#define TLBMISC_REG_RSV1_LSB 25
+#define TLBMISC_REG_RSV1_MSB 31
+#define TLBMISC_REG_RSV1_SZ 7
+#define TLBMISC_REG_RSV1_MASK 0x7f
+#define TLBMISC_REG_SZ 24
+#define TLBMISC_REG_MASK 0xffffff
+#define TLBMISC_REG_WAY_LSB 20
+#define TLBMISC_REG_WAY_MSB 22
+#define TLBMISC_REG_WAY_SZ 3
+#define TLBMISC_REG_WAY_MASK 0x7
+#define TLBMISC_REG_WE_LSB 23
+#define TLBMISC_REG_WE_MSB 23
+#define TLBMISC_REG_WE_SZ 1
+#define TLBMISC_REG_WE_MASK 0x1
+
+/* Macros to extract instruction fields */
+#define GET_IW_A(Iw) \
+ (((Iw) >> IW_A_LSB) & IW_A_MASK)
+#define SET_IW_A(Iw, Val) \
+ Iw = (((Iw) & (~(IW_A_MASK << IW_A_LSB))) | \
+ (((Val) & IW_A_MASK) << IW_A_LSB))
+#define GET_IW_B(Iw) \
+ (((Iw) >> IW_B_LSB) & IW_B_MASK)
+#define SET_IW_B(Iw, Val) \
+ Iw = (((Iw) & (~(IW_B_MASK << IW_B_LSB))) | \
+ (((Val) & IW_B_MASK) << IW_B_LSB))
+#define GET_IW_C(Iw) \
+ (((Iw) >> IW_C_LSB) & IW_C_MASK)
+#define SET_IW_C(Iw, Val) \
+ Iw = (((Iw) & (~(IW_C_MASK << IW_C_LSB))) | \
+ (((Val) & IW_C_MASK) << IW_C_LSB))
+#define GET_IW_CONTROL_REGNUM(Iw) \
+ (((Iw) >> IW_CONTROL_REGNUM_LSB) & IW_CONTROL_REGNUM_MASK)
+#define SET_IW_CONTROL_REGNUM(Iw, Val) \
+ Iw = (((Iw) & (~(IW_CONTROL_REGNUM_MASK << IW_CONTROL_REGNUM_LSB))) | \
+ (((Val) & IW_CONTROL_REGNUM_MASK) << IW_CONTROL_REGNUM_LSB))
+#define GET_IW_CUSTOM_N(Iw) \
+ (((Iw) >> IW_CUSTOM_N_LSB) & IW_CUSTOM_N_MASK)
+#define SET_IW_CUSTOM_N(Iw, Val) \
+ Iw = (((Iw) & (~(IW_CUSTOM_N_MASK << IW_CUSTOM_N_LSB))) | \
+ (((Val) & IW_CUSTOM_N_MASK) << IW_CUSTOM_N_LSB))
+#define GET_IW_CUSTOM_READRA(Iw) \
+ (((Iw) >> IW_CUSTOM_READRA_LSB) & IW_CUSTOM_READRA_MASK)
+#define SET_IW_CUSTOM_READRA(Iw, Val) \
+ Iw = (((Iw) & (~(IW_CUSTOM_READRA_MASK << IW_CUSTOM_READRA_LSB))) | \
+ (((Val) & IW_CUSTOM_READRA_MASK) << IW_CUSTOM_READRA_LSB))
+#define GET_IW_CUSTOM_READRB(Iw) \
+ (((Iw) >> IW_CUSTOM_READRB_LSB) & IW_CUSTOM_READRB_MASK)
+#define SET_IW_CUSTOM_READRB(Iw, Val) \
+ Iw = (((Iw) & (~(IW_CUSTOM_READRB_MASK << IW_CUSTOM_READRB_LSB))) | \
+ (((Val) & IW_CUSTOM_READRB_MASK) << IW_CUSTOM_READRB_LSB))
+#define GET_IW_CUSTOM_WRITERC(Iw) \
+ (((Iw) >> IW_CUSTOM_WRITERC_LSB) & IW_CUSTOM_WRITERC_MASK)
+#define SET_IW_CUSTOM_WRITERC(Iw, Val) \
+ Iw = (((Iw) & (~(IW_CUSTOM_WRITERC_MASK << IW_CUSTOM_WRITERC_LSB))) | \
+ (((Val) & IW_CUSTOM_WRITERC_MASK) << IW_CUSTOM_WRITERC_LSB))
+#define GET_IW_IMM16(Iw) \
+ (((Iw) >> IW_IMM16_LSB) & IW_IMM16_MASK)
+#define SET_IW_IMM16(Iw, Val) \
+ Iw = (((Iw) & (~(IW_IMM16_MASK << IW_IMM16_LSB))) | \
+ (((Val) & IW_IMM16_MASK) << IW_IMM16_LSB))
+#define GET_IW_IMM26(Iw) \
+ (((Iw) >> IW_IMM26_LSB) & IW_IMM26_MASK)
+#define SET_IW_IMM26(Iw, Val) \
+ Iw = (((Iw) & (~(IW_IMM26_MASK << IW_IMM26_LSB))) | \
+ (((Val) & IW_IMM26_MASK) << IW_IMM26_LSB))
+#define GET_IW_MEMSZ(Iw) \
+ (((Iw) >> IW_MEMSZ_LSB) & IW_MEMSZ_MASK)
+#define SET_IW_MEMSZ(Iw, Val) \
+ Iw = (((Iw) & (~(IW_MEMSZ_MASK << IW_MEMSZ_LSB))) | \
+ (((Val) & IW_MEMSZ_MASK) << IW_MEMSZ_LSB))
+#define GET_IW_OP(Iw) \
+ (((Iw) >> IW_OP_LSB) & IW_OP_MASK)
+#define SET_IW_OP(Iw, Val) \
+ Iw = (((Iw) & (~(IW_OP_MASK << IW_OP_LSB))) | \
+ (((Val) & IW_OP_MASK) << IW_OP_LSB))
+#define GET_IW_OPX(Iw) \
+ (((Iw) >> IW_OPX_LSB) & IW_OPX_MASK)
+#define SET_IW_OPX(Iw, Val) \
+ Iw = (((Iw) & (~(IW_OPX_MASK << IW_OPX_LSB))) | \
+ (((Val) & IW_OPX_MASK) << IW_OPX_LSB))
+#define GET_IW_SHIFT_IMM5(Iw) \
+ (((Iw) >> IW_SHIFT_IMM5_LSB) & IW_SHIFT_IMM5_MASK)
+#define SET_IW_SHIFT_IMM5(Iw, Val) \
+ Iw = (((Iw) & (~(IW_SHIFT_IMM5_MASK << IW_SHIFT_IMM5_LSB))) | \
+ (((Val) & IW_SHIFT_IMM5_MASK) << IW_SHIFT_IMM5_LSB))
+#define GET_IW_TRAP_BREAK_IMM5(Iw) \
+ (((Iw) >> IW_TRAP_BREAK_IMM5_LSB) & IW_TRAP_BREAK_IMM5_MASK)
+#define SET_IW_TRAP_BREAK_IMM5(Iw, Val) \
+ Iw = (((Iw) & (~(IW_TRAP_BREAK_IMM5_MASK << IW_TRAP_BREAK_IMM5_LSB))) | \
+ (((Val) & IW_TRAP_BREAK_IMM5_MASK) << IW_TRAP_BREAK_IMM5_LSB))
+
+/* Macros to extract control register fields */
+#define GET_BSTATUS_REG_MMU(Reg) \
+ (((Reg) >> BSTATUS_REG_MMU_LSB) & BSTATUS_REG_MMU_MASK)
+#define SET_BSTATUS_REG_MMU(Reg, Val) \
+ Reg = (((Reg) & (~(BSTATUS_REG_MMU_MASK << BSTATUS_REG_MMU_LSB))) | \
+ (((Val) & BSTATUS_REG_MMU_MASK) << BSTATUS_REG_MMU_LSB))
+#define GET_BSTATUS_REG_NO_MMU(Reg) \
+ (((Reg) >> BSTATUS_REG_NO_MMU_LSB) & BSTATUS_REG_NO_MMU_MASK)
+#define SET_BSTATUS_REG_NO_MMU(Reg, Val) \
+ Reg = (((Reg) & (~(BSTATUS_REG_NO_MMU_MASK << BSTATUS_REG_NO_MMU_LSB))) | \
+ (((Val) & BSTATUS_REG_NO_MMU_MASK) << BSTATUS_REG_NO_MMU_LSB))
+#define GET_ESTATUS_REG_MMU(Reg) \
+ (((Reg) >> ESTATUS_REG_MMU_LSB) & ESTATUS_REG_MMU_MASK)
+#define SET_ESTATUS_REG_MMU(Reg, Val) \
+ Reg = (((Reg) & (~(ESTATUS_REG_MMU_MASK << ESTATUS_REG_MMU_LSB))) | \
+ (((Val) & ESTATUS_REG_MMU_MASK) << ESTATUS_REG_MMU_LSB))
+#define GET_ESTATUS_REG_NO_MMU(Reg) \
+ (((Reg) >> ESTATUS_REG_NO_MMU_LSB) & ESTATUS_REG_NO_MMU_MASK)
+#define SET_ESTATUS_REG_NO_MMU(Reg, Val) \
+ Reg = (((Reg) & (~(ESTATUS_REG_NO_MMU_MASK << ESTATUS_REG_NO_MMU_LSB))) | \
+ (((Val) & ESTATUS_REG_NO_MMU_MASK) << ESTATUS_REG_NO_MMU_LSB))
+#define GET_EXCEPTION_REG_MEA(Reg) \
+ (((Reg) >> EXCEPTION_REG_MEA_LSB) & EXCEPTION_REG_MEA_MASK)
+#define SET_EXCEPTION_REG_MEA(Reg, Val) \
+ Reg = (((Reg) & (~(EXCEPTION_REG_MEA_MASK << EXCEPTION_REG_MEA_LSB))) | \
+ (((Val) & EXCEPTION_REG_MEA_MASK) << EXCEPTION_REG_MEA_LSB))
+#define GET_EXCEPTION_REG_MEE(Reg) \
+ (((Reg) >> EXCEPTION_REG_MEE_LSB) & EXCEPTION_REG_MEE_MASK)
+#define SET_EXCEPTION_REG_MEE(Reg, Val) \
+ Reg = (((Reg) & (~(EXCEPTION_REG_MEE_MASK << EXCEPTION_REG_MEE_LSB))) | \
+ (((Val) & EXCEPTION_REG_MEE_MASK) << EXCEPTION_REG_MEE_LSB))
+#define GET_PTEADDR_REG_PTBASE(Reg) \
+ (((Reg) >> PTEADDR_REG_PTBASE_LSB) & PTEADDR_REG_PTBASE_MASK)
+#define SET_PTEADDR_REG_PTBASE(Reg, Val) \
+ Reg = (((Reg) & (~(PTEADDR_REG_PTBASE_MASK << PTEADDR_REG_PTBASE_LSB))) | \
+ (((Val) & PTEADDR_REG_PTBASE_MASK) << PTEADDR_REG_PTBASE_LSB))
+#define GET_PTEADDR_REG_RSV(Reg) \
+ (((Reg) >> PTEADDR_REG_RSV_LSB) & PTEADDR_REG_RSV_MASK)
+#define SET_PTEADDR_REG_RSV(Reg, Val) \
+ Reg = (((Reg) & (~(PTEADDR_REG_RSV_MASK << PTEADDR_REG_RSV_LSB))) | \
+ (((Val) & PTEADDR_REG_RSV_MASK) << PTEADDR_REG_RSV_LSB))
+#define GET_PTEADDR_REG_VPN(Reg) \
+ (((Reg) >> PTEADDR_REG_VPN_LSB) & PTEADDR_REG_VPN_MASK)
+#define SET_PTEADDR_REG_VPN(Reg, Val) \
+ Reg = (((Reg) & (~(PTEADDR_REG_VPN_MASK << PTEADDR_REG_VPN_LSB))) | \
+ (((Val) & PTEADDR_REG_VPN_MASK) << PTEADDR_REG_VPN_LSB))
+#define GET_SIM_REG_PERF_CNT_CLR(Reg) \
+ (((Reg) >> SIM_REG_PERF_CNT_CLR_LSB) & SIM_REG_PERF_CNT_CLR_MASK)
+#define SET_SIM_REG_PERF_CNT_CLR(Reg, Val) \
+ Reg = (((Reg) & (~(SIM_REG_PERF_CNT_CLR_MASK << SIM_REG_PERF_CNT_CLR_LSB))) | \
+ (((Val) & SIM_REG_PERF_CNT_CLR_MASK) << SIM_REG_PERF_CNT_CLR_LSB))
+#define GET_SIM_REG_PERF_CNT_EN(Reg) \
+ (((Reg) >> SIM_REG_PERF_CNT_EN_LSB) & SIM_REG_PERF_CNT_EN_MASK)
+#define SET_SIM_REG_PERF_CNT_EN(Reg, Val) \
+ Reg = (((Reg) & (~(SIM_REG_PERF_CNT_EN_MASK << SIM_REG_PERF_CNT_EN_LSB))) | \
+ (((Val) & SIM_REG_PERF_CNT_EN_MASK) << SIM_REG_PERF_CNT_EN_LSB))
+#define GET_SIM_REG_SHOW_DTLB(Reg) \
+ (((Reg) >> SIM_REG_SHOW_DTLB_LSB) & SIM_REG_SHOW_DTLB_MASK)
+#define SET_SIM_REG_SHOW_DTLB(Reg, Val) \
+ Reg = (((Reg) & (~(SIM_REG_SHOW_DTLB_MASK << SIM_REG_SHOW_DTLB_LSB))) | \
+ (((Val) & SIM_REG_SHOW_DTLB_MASK) << SIM_REG_SHOW_DTLB_LSB))
+#define GET_SIM_REG_SHOW_ITLB(Reg) \
+ (((Reg) >> SIM_REG_SHOW_ITLB_LSB) & SIM_REG_SHOW_ITLB_MASK)
+#define SET_SIM_REG_SHOW_ITLB(Reg, Val) \
+ Reg = (((Reg) & (~(SIM_REG_SHOW_ITLB_MASK << SIM_REG_SHOW_ITLB_LSB))) | \
+ (((Val) & SIM_REG_SHOW_ITLB_MASK) << SIM_REG_SHOW_ITLB_LSB))
+#define GET_SIM_REG_SHOW_MMU_REGS(Reg) \
+ (((Reg) >> SIM_REG_SHOW_MMU_REGS_LSB) & SIM_REG_SHOW_MMU_REGS_MASK)
+#define SET_SIM_REG_SHOW_MMU_REGS(Reg, Val) \
+ Reg = (((Reg) & (~(SIM_REG_SHOW_MMU_REGS_MASK << SIM_REG_SHOW_MMU_REGS_LSB))) | \
+ (((Val) & SIM_REG_SHOW_MMU_REGS_MASK) << SIM_REG_SHOW_MMU_REGS_LSB))
+#define GET_SIM_REG_STOP(Reg) \
+ (((Reg) >> SIM_REG_STOP_LSB) & SIM_REG_STOP_MASK)
+#define SET_SIM_REG_STOP(Reg, Val) \
+ Reg = (((Reg) & (~(SIM_REG_STOP_MASK << SIM_REG_STOP_LSB))) | \
+ (((Val) & SIM_REG_STOP_MASK) << SIM_REG_STOP_LSB))
+#define GET_STATUS_REG_EH(Reg) \
+ (((Reg) >> STATUS_REG_EH_LSB) & STATUS_REG_EH_MASK)
+#define SET_STATUS_REG_EH(Reg, Val) \
+ Reg = (((Reg) & (~(STATUS_REG_EH_MASK << STATUS_REG_EH_LSB))) | \
+ (((Val) & STATUS_REG_EH_MASK) << STATUS_REG_EH_LSB))
+#define GET_STATUS_REG_MMU(Reg) \
+ (((Reg) >> STATUS_REG_MMU_LSB) & STATUS_REG_MMU_MASK)
+#define SET_STATUS_REG_MMU(Reg, Val) \
+ Reg = (((Reg) & (~(STATUS_REG_MMU_MASK << STATUS_REG_MMU_LSB))) | \
+ (((Val) & STATUS_REG_MMU_MASK) << STATUS_REG_MMU_LSB))
+#define GET_STATUS_REG_MMU_RSV(Reg) \
+ (((Reg) >> STATUS_REG_MMU_RSV_LSB) & STATUS_REG_MMU_RSV_MASK)
+#define SET_STATUS_REG_MMU_RSV(Reg, Val) \
+ Reg = (((Reg) & (~(STATUS_REG_MMU_RSV_MASK << STATUS_REG_MMU_RSV_LSB))) | \
+ (((Val) & STATUS_REG_MMU_RSV_MASK) << STATUS_REG_MMU_RSV_LSB))
+#define GET_STATUS_REG_NO_MMU(Reg) \
+ (((Reg) >> STATUS_REG_NO_MMU_LSB) & STATUS_REG_NO_MMU_MASK)
+#define SET_STATUS_REG_NO_MMU(Reg, Val) \
+ Reg = (((Reg) & (~(STATUS_REG_NO_MMU_MASK << STATUS_REG_NO_MMU_LSB))) | \
+ (((Val) & STATUS_REG_NO_MMU_MASK) << STATUS_REG_NO_MMU_LSB))
+#define GET_STATUS_REG_NO_MMU_RSV(Reg) \
+ (((Reg) >> STATUS_REG_NO_MMU_RSV_LSB) & STATUS_REG_NO_MMU_RSV_MASK)
+#define SET_STATUS_REG_NO_MMU_RSV(Reg, Val) \
+ Reg = (((Reg) & (~(STATUS_REG_NO_MMU_RSV_MASK << STATUS_REG_NO_MMU_RSV_LSB))) | \
+ (((Val) & STATUS_REG_NO_MMU_RSV_MASK) << STATUS_REG_NO_MMU_RSV_LSB))
+#define GET_STATUS_REG_PIE(Reg) \
+ (((Reg) >> STATUS_REG_PIE_LSB) & STATUS_REG_PIE_MASK)
+#define SET_STATUS_REG_PIE(Reg, Val) \
+ Reg = (((Reg) & (~(STATUS_REG_PIE_MASK << STATUS_REG_PIE_LSB))) | \
+ (((Val) & STATUS_REG_PIE_MASK) << STATUS_REG_PIE_LSB))
+#define GET_STATUS_REG_U(Reg) \
+ (((Reg) >> STATUS_REG_U_LSB) & STATUS_REG_U_MASK)
+#define SET_STATUS_REG_U(Reg, Val) \
+ Reg = (((Reg) & (~(STATUS_REG_U_MASK << STATUS_REG_U_LSB))) | \
+ (((Val) & STATUS_REG_U_MASK) << STATUS_REG_U_LSB))
+#define GET_TLBACC_REG_C(Reg) \
+ (((Reg) >> TLBACC_REG_C_LSB) & TLBACC_REG_C_MASK)
+#define SET_TLBACC_REG_C(Reg, Val) \
+ Reg = (((Reg) & (~(TLBACC_REG_C_MASK << TLBACC_REG_C_LSB))) | \
+ (((Val) & TLBACC_REG_C_MASK) << TLBACC_REG_C_LSB))
+#define GET_TLBACC_REG_G(Reg) \
+ (((Reg) >> TLBACC_REG_G_LSB) & TLBACC_REG_G_MASK)
+#define SET_TLBACC_REG_G(Reg, Val) \
+ Reg = (((Reg) & (~(TLBACC_REG_G_MASK << TLBACC_REG_G_LSB))) | \
+ (((Val) & TLBACC_REG_G_MASK) << TLBACC_REG_G_LSB))
+#define GET_TLBACC_REG_IG(Reg) \
+ (((Reg) >> TLBACC_REG_IG_LSB) & TLBACC_REG_IG_MASK)
+#define SET_TLBACC_REG_IG(Reg, Val) \
+ Reg = (((Reg) & (~(TLBACC_REG_IG_MASK << TLBACC_REG_IG_LSB))) | \
+ (((Val) & TLBACC_REG_IG_MASK) << TLBACC_REG_IG_LSB))
+#define GET_TLBACC_REG_PFN(Reg) \
+ (((Reg) >> TLBACC_REG_PFN_LSB) & TLBACC_REG_PFN_MASK)
+#define SET_TLBACC_REG_PFN(Reg, Val) \
+ Reg = (((Reg) & (~(TLBACC_REG_PFN_MASK << TLBACC_REG_PFN_LSB))) | \
+ (((Val) & TLBACC_REG_PFN_MASK) << TLBACC_REG_PFN_LSB))
+#define GET_TLBACC_REG_R(Reg) \
+ (((Reg) >> TLBACC_REG_R_LSB) & TLBACC_REG_R_MASK)
+#define SET_TLBACC_REG_R(Reg, Val) \
+ Reg = (((Reg) & (~(TLBACC_REG_R_MASK << TLBACC_REG_R_LSB))) | \
+ (((Val) & TLBACC_REG_R_MASK) << TLBACC_REG_R_LSB))
+#define GET_TLBACC_REG_W(Reg) \
+ (((Reg) >> TLBACC_REG_W_LSB) & TLBACC_REG_W_MASK)
+#define SET_TLBACC_REG_W(Reg, Val) \
+ Reg = (((Reg) & (~(TLBACC_REG_W_MASK << TLBACC_REG_W_LSB))) | \
+ (((Val) & TLBACC_REG_W_MASK) << TLBACC_REG_W_LSB))
+#define GET_TLBACC_REG_X(Reg) \
+ (((Reg) >> TLBACC_REG_X_LSB) & TLBACC_REG_X_MASK)
+#define SET_TLBACC_REG_X(Reg, Val) \
+ Reg = (((Reg) & (~(TLBACC_REG_X_MASK << TLBACC_REG_X_LSB))) | \
+ (((Val) & TLBACC_REG_X_MASK) << TLBACC_REG_X_LSB))
+#define GET_TLBMISC_REG_BAD(Reg) \
+ (((Reg) >> TLBMISC_REG_BAD_LSB) & TLBMISC_REG_BAD_MASK)
+#define SET_TLBMISC_REG_BAD(Reg, Val) \
+ Reg = (((Reg) & (~(TLBMISC_REG_BAD_MASK << TLBMISC_REG_BAD_LSB))) | \
+ (((Val) & TLBMISC_REG_BAD_MASK) << TLBMISC_REG_BAD_LSB))
+#define GET_TLBMISC_REG_D(Reg) \
+ (((Reg) >> TLBMISC_REG_D_LSB) & TLBMISC_REG_D_MASK)
+#define SET_TLBMISC_REG_D(Reg, Val) \
+ Reg = (((Reg) & (~(TLBMISC_REG_D_MASK << TLBMISC_REG_D_LSB))) | \
+ (((Val) & TLBMISC_REG_D_MASK) << TLBMISC_REG_D_LSB))
+#define GET_TLBMISC_REG_DBL(Reg) \
+ (((Reg) >> TLBMISC_REG_DBL_LSB) & TLBMISC_REG_DBL_MASK)
+#define SET_TLBMISC_REG_DBL(Reg, Val) \
+ Reg = (((Reg) & (~(TLBMISC_REG_DBL_MASK << TLBMISC_REG_DBL_LSB))) | \
+ (((Val) & TLBMISC_REG_DBL_MASK) << TLBMISC_REG_DBL_LSB))
+#define GET_TLBMISC_REG_PERM(Reg) \
+ (((Reg) >> TLBMISC_REG_PERM_LSB) & TLBMISC_REG_PERM_MASK)
+#define SET_TLBMISC_REG_PERM(Reg, Val) \
+ Reg = (((Reg) & (~(TLBMISC_REG_PERM_MASK << TLBMISC_REG_PERM_LSB))) | \
+ (((Val) & TLBMISC_REG_PERM_MASK) << TLBMISC_REG_PERM_LSB))
+#define GET_TLBMISC_REG_PID(Reg) \
+ (((Reg) >> TLBMISC_REG_PID_LSB) & TLBMISC_REG_PID_MASK)
+#define SET_TLBMISC_REG_PID(Reg, Val) \
+ Reg = (((Reg) & (~(TLBMISC_REG_PID_MASK << TLBMISC_REG_PID_LSB))) | \
+ (((Val) & TLBMISC_REG_PID_MASK) << TLBMISC_REG_PID_LSB))
+#define GET_TLBMISC_REG_RD(Reg) \
+ (((Reg) >> TLBMISC_REG_RD_LSB) & TLBMISC_REG_RD_MASK)
+#define SET_TLBMISC_REG_RD(Reg, Val) \
+ Reg = (((Reg) & (~(TLBMISC_REG_RD_MASK << TLBMISC_REG_RD_LSB))) | \
+ (((Val) & TLBMISC_REG_RD_MASK) << TLBMISC_REG_RD_LSB))
+#define GET_TLBMISC_REG_RSV0(Reg) \
+ (((Reg) >> TLBMISC_REG_RSV0_LSB) & TLBMISC_REG_RSV0_MASK)
+#define SET_TLBMISC_REG_RSV0(Reg, Val) \
+ Reg = (((Reg) & (~(TLBMISC_REG_RSV0_MASK << TLBMISC_REG_RSV0_LSB))) | \
+ (((Val) & TLBMISC_REG_RSV0_MASK) << TLBMISC_REG_RSV0_LSB))
+#define GET_TLBMISC_REG_RSV1(Reg) \
+ (((Reg) >> TLBMISC_REG_RSV1_LSB) & TLBMISC_REG_RSV1_MASK)
+#define SET_TLBMISC_REG_RSV1(Reg, Val) \
+ Reg = (((Reg) & (~(TLBMISC_REG_RSV1_MASK << TLBMISC_REG_RSV1_LSB))) | \
+ (((Val) & TLBMISC_REG_RSV1_MASK) << TLBMISC_REG_RSV1_LSB))
+#define GET_TLBMISC_REG_WAY(Reg) \
+ (((Reg) >> TLBMISC_REG_WAY_LSB) & TLBMISC_REG_WAY_MASK)
+#define SET_TLBMISC_REG_WAY(Reg, Val) \
+ Reg = (((Reg) & (~(TLBMISC_REG_WAY_MASK << TLBMISC_REG_WAY_LSB))) | \
+ (((Val) & TLBMISC_REG_WAY_MASK) << TLBMISC_REG_WAY_LSB))
+#define GET_TLBMISC_REG_WE(Reg) \
+ (((Reg) >> TLBMISC_REG_WE_LSB) & TLBMISC_REG_WE_MASK)
+#define SET_TLBMISC_REG_WE(Reg, Val) \
+ Reg = (((Reg) & (~(TLBMISC_REG_WE_MASK << TLBMISC_REG_WE_LSB))) | \
+ (((Val) & TLBMISC_REG_WE_MASK) << TLBMISC_REG_WE_LSB))
+
+/* Macros to extract MMU fields */
+#define GET_MMU_ADDR_BYPASS_TLB_CACHEABLE(Addr) \
+ (((Addr) >> MMU_ADDR_BYPASS_TLB_CACHEABLE_LSB) & MMU_ADDR_BYPASS_TLB_CACHEABLE_MASK)
+#define SET_MMU_ADDR_BYPASS_TLB_CACHEABLE(Addr, Val) \
+ Addr = (((Addr) & (~(MMU_ADDR_BYPASS_TLB_CACHEABLE_MASK << MMU_ADDR_BYPASS_TLB_CACHEABLE_LSB))) | \
+ (((Val) & MMU_ADDR_BYPASS_TLB_CACHEABLE_MASK) << MMU_ADDR_BYPASS_TLB_CACHEABLE_LSB))
+#define GET_MMU_ADDR_BYPASS_TLB(Addr) \
+ (((Addr) >> MMU_ADDR_BYPASS_TLB_LSB) & MMU_ADDR_BYPASS_TLB_MASK)
+#define SET_MMU_ADDR_BYPASS_TLB(Addr, Val) \
+ Addr = (((Addr) & (~(MMU_ADDR_BYPASS_TLB_MASK << MMU_ADDR_BYPASS_TLB_LSB))) | \
+ (((Val) & MMU_ADDR_BYPASS_TLB_MASK) << MMU_ADDR_BYPASS_TLB_LSB))
+#define GET_MMU_ADDR_BYPASS_TLB_PADDR(Addr) \
+ (((Addr) >> MMU_ADDR_BYPASS_TLB_PADDR_LSB) & MMU_ADDR_BYPASS_TLB_PADDR_MASK)
+#define SET_MMU_ADDR_BYPASS_TLB_PADDR(Addr, Val) \
+ Addr = (((Addr) & (~(MMU_ADDR_BYPASS_TLB_PADDR_MASK << MMU_ADDR_BYPASS_TLB_PADDR_LSB))) | \
+ (((Val) & MMU_ADDR_BYPASS_TLB_PADDR_MASK) << MMU_ADDR_BYPASS_TLB_PADDR_LSB))
+#define GET_MMU_ADDR_IO_REGION(Addr) \
+ (((Addr) >> MMU_ADDR_IO_REGION_LSB) & MMU_ADDR_IO_REGION_MASK)
+#define SET_MMU_ADDR_IO_REGION(Addr, Val) \
+ Addr = (((Addr) & (~(MMU_ADDR_IO_REGION_MASK << MMU_ADDR_IO_REGION_LSB))) | \
+ (((Val) & MMU_ADDR_IO_REGION_MASK) << MMU_ADDR_IO_REGION_LSB))
+#define GET_MMU_ADDR_KERNEL_MMU_REGION(Addr) \
+ (((Addr) >> MMU_ADDR_KERNEL_MMU_REGION_LSB) & MMU_ADDR_KERNEL_MMU_REGION_MASK)
+#define SET_MMU_ADDR_KERNEL_MMU_REGION(Addr, Val) \
+ Addr = (((Addr) & (~(MMU_ADDR_KERNEL_MMU_REGION_MASK << MMU_ADDR_KERNEL_MMU_REGION_LSB))) | \
+ (((Val) & MMU_ADDR_KERNEL_MMU_REGION_MASK) << MMU_ADDR_KERNEL_MMU_REGION_LSB))
+#define GET_MMU_ADDR_KERNEL_REGION(Addr) \
+ (((Addr) >> MMU_ADDR_KERNEL_REGION_LSB) & MMU_ADDR_KERNEL_REGION_MASK)
+#define SET_MMU_ADDR_KERNEL_REGION(Addr, Val) \
+ Addr = (((Addr) & (~(MMU_ADDR_KERNEL_REGION_MASK << MMU_ADDR_KERNEL_REGION_LSB))) | \
+ (((Val) & MMU_ADDR_KERNEL_REGION_MASK) << MMU_ADDR_KERNEL_REGION_LSB))
+#define GET_MMU_ADDR_PAGE_OFFSET(Addr) \
+ (((Addr) >> MMU_ADDR_PAGE_OFFSET_LSB) & MMU_ADDR_PAGE_OFFSET_MASK)
+#define SET_MMU_ADDR_PAGE_OFFSET(Addr, Val) \
+ Addr = (((Addr) & (~(MMU_ADDR_PAGE_OFFSET_MASK << MMU_ADDR_PAGE_OFFSET_LSB))) | \
+ (((Val) & MMU_ADDR_PAGE_OFFSET_MASK) << MMU_ADDR_PAGE_OFFSET_LSB))
+#define GET_MMU_ADDR_PFN(Addr) \
+ (((Addr) >> MMU_ADDR_PFN_LSB) & MMU_ADDR_PFN_MASK)
+#define SET_MMU_ADDR_PFN(Addr, Val) \
+ Addr = (((Addr) & (~(MMU_ADDR_PFN_MASK << MMU_ADDR_PFN_LSB))) | \
+ (((Val) & MMU_ADDR_PFN_MASK) << MMU_ADDR_PFN_LSB))
+#define GET_MMU_ADDR_USER_REGION(Addr) \
+ (((Addr) >> MMU_ADDR_USER_REGION_LSB) & MMU_ADDR_USER_REGION_MASK)
+#define SET_MMU_ADDR_USER_REGION(Addr, Val) \
+ Addr = (((Addr) & (~(MMU_ADDR_USER_REGION_MASK << MMU_ADDR_USER_REGION_LSB))) | \
+ (((Val) & MMU_ADDR_USER_REGION_MASK) << MMU_ADDR_USER_REGION_LSB))
+#define GET_MMU_ADDR_VPN(Addr) \
+ (((Addr) >> MMU_ADDR_VPN_LSB) & MMU_ADDR_VPN_MASK)
+#define SET_MMU_ADDR_VPN(Addr, Val) \
+ Addr = (((Addr) & (~(MMU_ADDR_VPN_MASK << MMU_ADDR_VPN_LSB))) | \
+ (((Val) & MMU_ADDR_VPN_MASK) << MMU_ADDR_VPN_LSB))
+
+/* OP instruction values */
+#define OP_ADDI 4
+#define OP_ANDHI 44
+#define OP_ANDI 12
+#define OP_BEQ 38
+#define OP_BGE 14
+#define OP_BGEU 46
+#define OP_BLT 22
+#define OP_BLTU 54
+#define OP_BNE 30
+#define OP_BR 6
+#define OP_CALL 0
+#define OP_CMPEQI 32
+#define OP_CMPGEI 8
+#define OP_CMPGEUI 40
+#define OP_CMPLTI 16
+#define OP_CMPLTUI 48
+#define OP_CMPNEI 24
+#define OP_CUSTOM 50
+#define OP_FLUSHD 59
+#define OP_FLUSHDA 27
+#define OP_INITD 51
+#define OP_JMPI 1
+#define OP_LDB 7
+#define OP_LDBIO 39
+#define OP_LDBU 3
+#define OP_LDBUIO 35
+#define OP_LDH 15
+#define OP_LDHIO 47
+#define OP_LDHU 11
+#define OP_LDHUIO 43
+#define OP_LDW 23
+#define OP_LDWIO 55
+#define OP_MULI 36
+#define OP_OPX 58
+#define OP_ORHI 52
+#define OP_ORI 20
+#define OP_STB 5
+#define OP_STBIO 37
+#define OP_STH 13
+#define OP_STHIO 45
+#define OP_STW 21
+#define OP_STWIO 53
+#define OP_XORHI 60
+#define OP_XORI 28
+
+/* OPX instruction values */
+#define OPX_ADD 49
+#define OPX_AND 14
+#define OPX_BREAK 52
+#define OPX_BRET 9
+#define OPX_CALLR 29
+#define OPX_CMPEQ 32
+#define OPX_CMPGE 8
+#define OPX_CMPGEU 40
+#define OPX_CMPLT 16
+#define OPX_CMPLTU 48
+#define OPX_CMPNE 24
+#define OPX_CRST 62
+#define OPX_DIV 37
+#define OPX_DIVU 36
+#define OPX_ERET 1
+#define OPX_FLUSHI 12
+#define OPX_FLUSHP 4
+#define OPX_HBREAK 53
+#define OPX_INITI 41
+#define OPX_INTR 61
+#define OPX_JMP 13
+#define OPX_MUL 39
+#define OPX_MULXSS 31
+#define OPX_MULXSU 23
+#define OPX_MULXUU 7
+#define OPX_NEXTPC 28
+#define OPX_NOR 6
+#define OPX_OR 22
+#define OPX_RDCTL 38
+#define OPX_RET 5
+#define OPX_ROL 3
+#define OPX_ROLI 2
+#define OPX_ROR 11
+#define OPX_SLL 19
+#define OPX_SLLI 18
+#define OPX_SRA 59
+#define OPX_SRAI 58
+#define OPX_SRL 27
+#define OPX_SRLI 26
+#define OPX_SUB 57
+#define OPX_SYNC 54
+#define OPX_TRAP 45
+#define OPX_WRCTL 46
+#define OPX_XOR 30
+
+/* Macros to detect sub-opcode instructions */
+#define IS_OPX_INST(Iw) (GET_IW_OP(Iw) == OP_OPX)
+#define IS_CUSTOM_INST(Iw) (GET_IW_OP(Iw) == OP_CUSTOM)
+
+/* Instruction property macros */
+#define IW_PROP_RESERVED_OP(Iw) (0)
+
+#define IW_PROP_RESERVED_OPX(Iw) (0)
+
+#define IW_PROP_RESERVED(Iw) (0)
+
+#define IW_PROP_SUPERVISOR_ONLY(Iw) ( \
+ (op_prop_supervisor_only[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_supervisor_only[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_supervisor_only[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_supervisor_only[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_INITI_FLUSHI(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_INITI) && IS_OPX_INST(Iw)) || \
+ ((GET_IW_OPX((Iw)) == OPX_FLUSHI) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_FLUSH_PIPE(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_flush_pipe[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_flush_pipe[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_JMP_INDIRECT_NON_TRAP(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_jmp_indirect_non_trap[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_jmp_indirect_non_trap[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_JMP_INDIRECT(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_jmp_indirect[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_jmp_indirect[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_JMP_DIRECT(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_CALL)) || \
+ ((GET_IW_OP((Iw)) == OP_JMPI)) \
+ ) \
+ \
+)
+
+#define IW_PROP_MUL_LSW(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_MULI)) || \
+ ((GET_IW_OPX((Iw)) == OPX_MUL) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_MULX(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_mulx[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_mulx[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_MUL(Iw) ( \
+ (op_prop_mul[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_mul[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_mul[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_mul[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_DIV_UNSIGNED(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_DIVU) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_DIV_SIGNED(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_DIV) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_DIV(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_DIVU) && IS_OPX_INST(Iw)) || \
+ ((GET_IW_OPX((Iw)) == OPX_DIV) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_UNIMPLEMENTED(Iw) (0)
+
+#define IW_PROP_IMPLICIT_DST_RETADDR(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_CALL)) \
+ ) \
+ \
+)
+
+#define IW_PROP_IMPLICIT_DST_ERETADDR(Iw) (0)
+
+#define IW_PROP_EXCEPTION(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_TRAP) && IS_OPX_INST(Iw)) || \
+ ((GET_IW_OPX((Iw)) == OPX_INTR) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_BREAK(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_BREAK) && IS_OPX_INST(Iw)) || \
+ ((GET_IW_OPX((Iw)) == OPX_HBREAK) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_CRST(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_CRST) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_WR_CTL_REG(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_wr_ctl_reg[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_wr_ctl_reg[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_UNCOND_CTI_NON_BR(Iw) ( \
+ (op_prop_uncond_cti_non_br[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_uncond_cti_non_br[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_uncond_cti_non_br[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_uncond_cti_non_br[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_RETADDR(Iw) ( \
+ (op_prop_retaddr[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_retaddr[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_retaddr[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_retaddr[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_SHIFT_LEFT(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_SLLI) && IS_OPX_INST(Iw)) || \
+ ((GET_IW_OPX((Iw)) == OPX_SLL) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_SHIFT_LOGICAL(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_shift_logical[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_shift_logical[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_ROT_LEFT(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_ROLI) && IS_OPX_INST(Iw)) || \
+ ((GET_IW_OPX((Iw)) == OPX_ROL) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_SHIFT_ROT_LEFT(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_shift_rot_left[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_shift_rot_left[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_SHIFT_RIGHT_LOGICAL(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_SRLI) && IS_OPX_INST(Iw)) || \
+ ((GET_IW_OPX((Iw)) == OPX_SRL) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_SHIFT_RIGHT_ARITH(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_SRAI) && IS_OPX_INST(Iw)) || \
+ ((GET_IW_OPX((Iw)) == OPX_SRA) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_SHIFT_RIGHT(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_shift_right[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_shift_right[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_ROT_RIGHT(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_ROR) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_SHIFT_ROT_RIGHT(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_shift_rot_right[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_shift_rot_right[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_SHIFT_ROT(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_shift_rot[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_shift_rot[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_SHIFT_ROT_IMM(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_shift_rot_imm[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_shift_rot_imm[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_ROTATE(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_rotate[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_rotate[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_LOGIC_REG(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_logic_reg[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_logic_reg[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_LOGIC_HI_IMM16(Iw) ( \
+ (op_prop_logic_hi_imm16[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_logic_hi_imm16[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_LOGIC_LO_IMM16(Iw) ( \
+ (op_prop_logic_lo_imm16[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_logic_lo_imm16[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_LOGIC_IMM16(Iw) ( \
+ (op_prop_logic_imm16[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_logic_imm16[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_LOGIC(Iw) ( \
+ (op_prop_logic[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_logic[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_logic[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_logic[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_UNSIGNED_LO_IMM16(Iw) ( \
+ (op_prop_unsigned_lo_imm16[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_unsigned_lo_imm16[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_unsigned_lo_imm16[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_unsigned_lo_imm16[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_ARITH_IMM16(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_ADDI)) || \
+ ((GET_IW_OP((Iw)) == OP_MULI)) \
+ ) \
+ \
+)
+
+#define IW_PROP_CMP_IMM16(Iw) ( \
+ (op_prop_cmp_imm16[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_cmp_imm16[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_JMPI(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_JMPI)) \
+ ) \
+ \
+)
+
+#define IW_PROP_CMP_IMM16_WITH_CALL_JMPI(Iw) ( \
+ (op_prop_cmp_imm16_with_call_jmpi[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_cmp_imm16_with_call_jmpi[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_CMP_REG(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_cmp_reg[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_cmp_reg[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_SRC_IMM5(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_src_imm5[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_src_imm5[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_CMP_WITH_LT(Iw) ( \
+ (op_prop_cmp_with_lt[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_cmp_with_lt[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_cmp_with_lt[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_cmp_with_lt[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_CMP_WITH_EQ(Iw) ( \
+ (op_prop_cmp_with_eq[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_cmp_with_eq[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_cmp_with_eq[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_cmp_with_eq[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_CMP_WITH_GE(Iw) ( \
+ (op_prop_cmp_with_ge[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_cmp_with_ge[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_cmp_with_ge[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_cmp_with_ge[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_CMP_WITH_NE(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_CMPNEI)) || \
+ ((GET_IW_OPX((Iw)) == OPX_CMPNE) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_CMP_ALU_SIGNED(Iw) ( \
+ (op_prop_cmp_alu_signed[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_cmp_alu_signed[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_cmp_alu_signed[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_cmp_alu_signed[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_CMP(Iw) ( \
+ (op_prop_cmp[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_cmp[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_cmp[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_cmp[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_BR_WITH_LT(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_BLT)) || \
+ ((GET_IW_OP((Iw)) == OP_BLTU)) \
+ ) \
+ \
+)
+
+#define IW_PROP_BR_WITH_GE(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_BGE)) || \
+ ((GET_IW_OP((Iw)) == OP_BGEU)) \
+ ) \
+ \
+)
+
+#define IW_PROP_BR_WITH_EQ(Iw) ( \
+ (op_prop_br_with_eq[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_br_with_eq[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_BR_WITH_NE(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_BNE)) \
+ ) \
+ \
+)
+
+#define IW_PROP_BR_ALU_SIGNED(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_BGE)) || \
+ ((GET_IW_OP((Iw)) == OP_BLT)) \
+ ) \
+ \
+)
+
+#define IW_PROP_BR_COND(Iw) ( \
+ (op_prop_br_cond[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_br_cond[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_BR_UNCOND(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_BR)) \
+ ) \
+ \
+)
+
+#define IW_PROP_BR(Iw) ( \
+ (op_prop_br[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_br[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_ALU_SUB(Iw) ( \
+ (op_prop_alu_sub[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_alu_sub[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_alu_sub[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_alu_sub[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_FORCE_XOR(Iw) ( \
+ (op_prop_force_xor[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_force_xor[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_force_xor[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_force_xor[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_LOAD8(Iw) ( \
+ (op_prop_load8[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_load8[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_LOAD16(Iw) ( \
+ (op_prop_load16[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_load16[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_LOAD32(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_LDW)) || \
+ ((GET_IW_OP((Iw)) == OP_LDWIO)) \
+ ) \
+ \
+)
+
+#define IW_PROP_LOAD_SIGNED(Iw) ( \
+ (op_prop_load_signed[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_load_signed[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_LOAD_UNSIGNED(Iw) ( \
+ (op_prop_load_unsigned[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_load_unsigned[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_LOAD(Iw) ( \
+ (op_prop_load[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_load[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_LOAD_INITD_FLUSHD_FLUSHDA(Iw) ( \
+ (op_prop_load_initd_flushd_flushda[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_load_initd_flushd_flushda[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_LOAD_NON_IO(Iw) ( \
+ (op_prop_load_non_io[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_load_non_io[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_STORE8(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_STB)) || \
+ ((GET_IW_OP((Iw)) == OP_STBIO)) \
+ ) \
+ \
+)
+
+#define IW_PROP_STORE16(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_STH)) || \
+ ((GET_IW_OP((Iw)) == OP_STHIO)) \
+ ) \
+ \
+)
+
+#define IW_PROP_STORE32(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_STW)) || \
+ ((GET_IW_OP((Iw)) == OP_STWIO)) \
+ ) \
+ \
+)
+
+#define IW_PROP_STORE(Iw) ( \
+ (op_prop_store[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_store[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_STORE_NON_IO(Iw) ( \
+ (op_prop_store_non_io[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_store_non_io[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_MEM(Iw) ( \
+ (op_prop_mem[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_mem[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_INITD(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_INITD)) \
+ ) \
+ \
+)
+
+#define IW_PROP_FLUSHD(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_FLUSHD)) \
+ ) \
+ \
+)
+
+#define IW_PROP_INITD_FLUSHD(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_INITD)) || \
+ ((GET_IW_OP((Iw)) == OP_FLUSHD)) \
+ ) \
+ \
+)
+
+#define IW_PROP_FLUSHDA(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_FLUSHDA)) \
+ ) \
+ \
+)
+
+#define IW_PROP_FLUSHD_FLUSHDA(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_FLUSHD)) || \
+ ((GET_IW_OP((Iw)) == OP_FLUSHDA)) \
+ ) \
+ \
+)
+
+#define IW_PROP_INITD_FLUSHD_FLUSHDA(Iw) ( \
+ (op_prop_initd_flushd_flushda[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_initd_flushd_flushda[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_LOAD_IO(Iw) ( \
+ (op_prop_load_io[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_load_io[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_STORE_IO(Iw) ( \
+ (op_prop_store_io[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_store_io[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_MEM_IO(Iw) ( \
+ (op_prop_mem_io[GET_IW_OP(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_mem_io[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_ARITH(Iw) ( \
+ (op_prop_arith[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_arith[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_arith[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_arith[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_A_NOT_SRC(Iw) ( \
+ ( \
+ ((GET_IW_OP((Iw)) == OP_CALL)) || \
+ ((GET_IW_OP((Iw)) == OP_JMPI)) \
+ ) \
+ || (IS_CUSTOM_INST(Iw) && !GET_IW_CUSTOM_READRA(Iw)) \
+)
+
+#define IW_PROP_B_NOT_SRC(Iw) ( \
+ (op_prop_b_not_src[GET_IW_OP(Iw)]) \
+ || (IS_CUSTOM_INST(Iw) && !GET_IW_CUSTOM_READRB(Iw)))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_b_not_src[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_IGNORE_DST(Iw) ( \
+ (op_prop_ignore_dst[GET_IW_OP(Iw)]) \
+ || (IS_CUSTOM_INST(Iw) && !GET_IW_CUSTOM_WRITERC(Iw)))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_ignore_dst[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_SRC2_CHOOSE_IMM(Iw) ( \
+ (op_prop_src2_choose_imm[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_src2_choose_imm[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_src2_choose_imm[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_src2_choose_imm[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_WRCTL_INST(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_WRCTL) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_RDCTL_INST(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_RDCTL) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_MUL_SRC1_SIGNED(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_MULXSS) && IS_OPX_INST(Iw)) || \
+ ((GET_IW_OPX((Iw)) == OPX_MULXSU) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_MUL_SRC2_SIGNED(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_MULXSS) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_MUL_SHIFT_SRC1_SIGNED(Iw) ( \
+ (IS_OPX_INST(Iw) && opx_prop_mul_shift_src1_signed[GET_IW_OPX(Iw)]))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_mul_shift_src1_signed[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_MUL_SHIFT_SRC2_SIGNED(Iw) ( \
+ ( \
+ ((GET_IW_OPX((Iw)) == OPX_MULXSS) && IS_OPX_INST(Iw)) \
+ ) \
+ \
+)
+
+#define IW_PROP_DONT_DISPLAY_DST_REG(Iw) ( \
+ (op_prop_dont_display_dst_reg[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_dont_display_dst_reg[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_dont_display_dst_reg[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_dont_display_dst_reg[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_DONT_DISPLAY_SRC1_REG(Iw) ( \
+ (op_prop_dont_display_src1_reg[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_dont_display_src1_reg[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_dont_display_src1_reg[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_dont_display_src1_reg[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_DONT_DISPLAY_SRC2_REG(Iw) ( \
+ (op_prop_dont_display_src2_reg[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_dont_display_src2_reg[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_dont_display_src2_reg[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_dont_display_src2_reg[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_SRC1_NO_X(Iw) ( \
+ (op_prop_src1_no_x[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_src1_no_x[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_src1_no_x[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_src1_no_x[64];
+#endif /* ALT_ASM_SRC */
+
+#define IW_PROP_SRC2_NO_X(Iw) ( \
+ (op_prop_src2_no_x[GET_IW_OP(Iw)] || \
+ (IS_OPX_INST(Iw) && opx_prop_src2_no_x[GET_IW_OPX(Iw)])))
+
+#ifndef ALT_ASM_SRC
+extern unsigned char op_prop_src2_no_x[64];
+#endif /* ALT_ASM_SRC */
+
+#ifndef ALT_ASM_SRC
+extern unsigned char opx_prop_src2_no_x[64];
+#endif /* ALT_ASM_SRC */
+
+/* Instruction types */
+#define INST_TYPE_OP 0
+#define INST_TYPE_OPX 1
+
+/* Canonical instruction codes independent of encoding */
+#define CALL_INST_CODE 0
+#define JMPI_INST_CODE 1
+#define LDBU_INST_CODE 2
+#define ADDI_INST_CODE 3
+#define STB_INST_CODE 4
+#define BR_INST_CODE 5
+#define LDB_INST_CODE 6
+#define CMPGEI_INST_CODE 7
+#define LDHU_INST_CODE 8
+#define ANDI_INST_CODE 9
+#define STH_INST_CODE 10
+#define BGE_INST_CODE 11
+#define LDH_INST_CODE 12
+#define CMPLTI_INST_CODE 13
+#define ORI_INST_CODE 14
+#define STW_INST_CODE 15
+#define BLT_INST_CODE 16
+#define LDW_INST_CODE 17
+#define CMPNEI_INST_CODE 18
+#define FLUSHDA_INST_CODE 19
+#define XORI_INST_CODE 20
+#define BNE_INST_CODE 21
+#define CMPEQI_INST_CODE 22
+#define LDBUIO_INST_CODE 23
+#define MULI_INST_CODE 24
+#define STBIO_INST_CODE 25
+#define BEQ_INST_CODE 26
+#define LDBIO_INST_CODE 27
+#define CMPGEUI_INST_CODE 28
+#define LDHUIO_INST_CODE 29
+#define ANDHI_INST_CODE 30
+#define STHIO_INST_CODE 31
+#define BGEU_INST_CODE 32
+#define LDHIO_INST_CODE 33
+#define CMPLTUI_INST_CODE 34
+#define CUSTOM_INST_CODE 35
+#define INITD_INST_CODE 36
+#define ORHI_INST_CODE 37
+#define STWIO_INST_CODE 38
+#define BLTU_INST_CODE 39
+#define LDWIO_INST_CODE 40
+#define FLUSHD_INST_CODE 41
+#define XORHI_INST_CODE 42
+#define ERET_INST_CODE 43
+#define ROLI_INST_CODE 44
+#define ROL_INST_CODE 45
+#define FLUSHP_INST_CODE 46
+#define RET_INST_CODE 47
+#define NOR_INST_CODE 48
+#define MULXUU_INST_CODE 49
+#define CMPGE_INST_CODE 50
+#define BRET_INST_CODE 51
+#define ROR_INST_CODE 52
+#define FLUSHI_INST_CODE 53
+#define JMP_INST_CODE 54
+#define AND_INST_CODE 55
+#define CMPLT_INST_CODE 56
+#define SLLI_INST_CODE 57
+#define SLL_INST_CODE 58
+#define OR_INST_CODE 59
+#define MULXSU_INST_CODE 60
+#define CMPNE_INST_CODE 61
+#define SRLI_INST_CODE 62
+#define SRL_INST_CODE 63
+#define NEXTPC_INST_CODE 64
+#define CALLR_INST_CODE 65
+#define XOR_INST_CODE 66
+#define MULXSS_INST_CODE 67
+#define CMPEQ_INST_CODE 68
+#define DIVU_INST_CODE 69
+#define DIV_INST_CODE 70
+#define RDCTL_INST_CODE 71
+#define MUL_INST_CODE 72
+#define CMPGEU_INST_CODE 73
+#define INITI_INST_CODE 74
+#define TRAP_INST_CODE 75
+#define WRCTL_INST_CODE 76
+#define CMPLTU_INST_CODE 77
+#define ADD_INST_CODE 78
+#define BREAK_INST_CODE 79
+#define HBREAK_INST_CODE 80
+#define SYNC_INST_CODE 81
+#define SUB_INST_CODE 82
+#define SRAI_INST_CODE 83
+#define SRA_INST_CODE 84
+#define INTR_INST_CODE 85
+#define CRST_INST_CODE 86
+#define RSV_INST_CODE 87
+#define NUM_NIOS2_INST_CODES 88
+
+#ifndef ALT_ASM_SRC
+/* Instruction information entry */
+typedef struct {
+ const char* name; /* Assembly-language instruction name */
+ int instType; /* INST_TYPE_OP or INST_TYPE_OPX */
+ unsigned opcode; /* Value of instruction word OP/OPX field */
+} Nios2InstInfo;
+
+extern Nios2InstInfo nios2InstInfo[NUM_NIOS2_INST_CODES];
+#endif /* ALT_ASM_SRC */
+
+/* Returns the instruction code given the 32-bit instruction word */
+#define GET_INST_CODE(Iw) \
+ (IS_OPX_INST(Iw) ? opxToInstCode[GET_IW_OPX(Iw)] : opToInstCode[GET_IW_OP(Iw)])
+
+#ifndef ALT_ASM_SRC
+extern int opToInstCode[64];
+extern int opxToInstCode[64];
+#endif /* ALT_ASM_SRC */
+
+/*
+ * MMU Memory Region Macros
+ */
+#define USER_REGION_MIN_VADDR 0x00000000
+#define USER_REGION_MAX_VADDR 0x7fffffff
+#define KERNEL_MMU_REGION_MIN_VADDR 0x80000000
+#define KERNEL_MMU_REGION_MAX_VADDR 0xbfffffff
+#define KERNEL_REGION_MIN_VADDR 0xc0000000
+#define KERNEL_REGION_MAX_VADDR 0xdfffffff
+#define IO_REGION_MIN_VADDR 0xe0000000
+#define IO_REGION_MAX_VADDR 0xffffffff
+
+#define MMU_PAGE_SIZE (0x1 << (MMU_ADDR_PAGE_OFFSET_SZ))
+
+#define isMmuUserRegion(Vaddr) \
+ (GET_MMU_ADDR_USER_REGION(Vaddr) == MMU_ADDR_USER_REGION)
+#define isMmuKernelMmuRegion(Vaddr) \
+ (GET_MMU_ADDR_KERNEL_MMU_REGION(Vaddr) == MMU_ADDR_KERNEL_MMU_REGION)
+#define isMmuKernelRegion(Vaddr) \
+ (GET_MMU_ADDR_KERNEL_REGION(Vaddr) == MMU_ADDR_KERNEL_REGION)
+#define isMmuIORegion(Vaddr) \
+ (GET_MMU_ADDR_IO_REGION(Vaddr) == MMU_ADDR_IO_REGION)
+
+/* Does this virtual address bypass the TLB? */
+#define vaddrBypassTlb(Vaddr) \
+ (GET_MMU_ADDR_BYPASS_TLB(Vaddr) == MMU_ADDR_BYPASS_TLB)
+
+/* If TLB is bypassed, is the address cacheable or uncachable. */
+#define vaddrBypassTlbCacheable(Vaddr) \
+ (GET_MMU_ADDR_BYPASS_TLB_CACHEABLE(Vaddr) == MMU_ADDR_BYPASS_TLB_CACHEABLE)
+
+/*
+ * Compute physical address for regions that bypass the TLB.
+ * Just need to clear some top bits.
+ */
+#define bypassTlbVaddrToPaddr(Vaddr) \
+ ((Vaddr) & (MMU_ADDR_BYPASS_TLB_PADDR_MASK << MMU_ADDR_BYPASS_TLB_PADDR_LSB))
+
+/*
+ * Will the physical address fit in the Kernel/IO region virtual address space?
+ */
+#define fitsInKernelRegion(Paddr) \
+ (GET_MMU_ADDR_KERNEL_REGION(Paddr) == 0)
+#define fitsInIORegion(Paddr) \
+ (GET_MMU_ADDR_IO_REGION(Paddr) == 0)
+
+/* Convert a physical address to a Kernel/IO region virtual address. */
+#define paddrToKernelRegionVaddr(Paddr) \
+ ((Paddr) | (MMU_ADDR_KERNEL_REGION << MMU_ADDR_KERNEL_REGION_LSB))
+#define paddrToIORegionVaddr(Paddr) \
+ ((Paddr) | (MMU_ADDR_IO_REGION << MMU_ADDR_IO_REGION_LSB))
+
+/*
+ * Convert a virtual address to a Kernel/IO region virtual address.
+ * Uses bypassTlbVaddrToPaddr to clear top bits.
+ */
+#define vaddrToKernelRegionVaddr(Vaddr) \
+ paddrToKernelRegionVaddr(bypassTlbVaddrToPaddr(Vaddr))
+#define vaddrToIORegionVaddr(Vaddr) \
+ paddrToIORegionVaddr(bypassTlbVaddrToPaddr(Vaddr))
+
+/* Convert between VPN/PFN and virtual/physical addresses. */
+#define vpnToVaddr(Vpn) ((Vpn) << MMU_ADDR_VPN_LSB)
+#define pfnToPaddr(Pfn) ((Pfn) << MMU_ADDR_PFN_LSB)
+#define vaddrToVpn(Vaddr) GET_MMU_ADDR_VPN(Vaddr)
+#define paddrToPfn(Paddr) GET_MMU_ADDR_PFN(Paddr)
+
+/* Bitwise OR with a KERNEL region address to make it an IO region address */
+#define KERNEL_TO_IO_REGION 0x20000000
+
+#endif /* _NIOS2_ISA_H_ */
diff --git a/include/opcode/nios2.h b/include/opcode/nios2.h
new file mode 100644
index 0000000..992bb80
--- /dev/null
+++ b/include/opcode/nios2.h
@@ -0,0 +1,361 @@
+/* nios2.h. Altera New Jersey opcode list for GAS, the GNU assembler.
+
+ Copyright (C) 2003
+ by Nigel Gray (ngray@altera.com).
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _NIOS2_H_
+#define _NIOS2_H_
+
+
+/****************************************************************************
+ * This file contains structures, bit masks and shift counts used
+ * by the GNU toolchain to define the New Jersey instruction set and
+ * access various opcode fields.
+ ****************************************************************************/
+
+enum overflow_type
+{
+ call_target_overflow = 0,
+ branch_target_overflow,
+ address_offset_overflow,
+ signed_immed16_overflow,
+ unsigned_immed16_overflow,
+ unsigned_immed5_overflow,
+ custom_opcode_overflow,
+ no_overflow
+};
+
+/*---------------------------------------------------------------------------
+ This structure holds information for a particular instruction
+ ---------------------------------------------------------------------------*/
+
+/* match When assembling, this
+ opcode is modified by the arguments to produce the actual opcode
+ that is used. If pinfo is INSN_MACRO, then this is 0. */
+
+/* mask If pinfo is not INSN_MACRO, then this is a bit mask for the
+ relevant portions of the opcode when disassembling. If the
+ actual opcode anded with the match field equals the opcode field,
+ then we have found the correct instruction. If pinfo is
+ INSN_MACRO, then this field is the macro identifier. */
+
+/* For a macro, this is INSN_MACRO. Otherwise, it is a collection
+ of bits describing the instruction, notably any relevant hazard
+ information. */
+
+struct nios2_opcode
+{
+ const char *name; /* The name of the instruction. */
+ const char *args; /* A string describing the arguments for this instruction. */
+ const char *args_test; /* Like args, but with an extra argument for the expected opcode */
+ unsigned long num_args; /* the number of arguments the instruction takes */
+ unsigned long match; /* The basic opcode for the instruction. */
+ unsigned long mask; /* mask for the opcode field of the instruction */
+ unsigned long pinfo; /* is this a real instruction or instruction macro */
+ enum overflow_type overflow_msg; /* msg template used to generate informative message when fixup overflows */
+};
+
+/* This value is used in the nios2_opcode.pinfo field to indicate that the instruction
+ is a macro or pseudo-op. This requires special treatment by the assembler, and is
+ used by the disassembler to determine whether to check for a nop */
+#define NIOS2_INSN_MACRO 0x80000000
+#define NIOS2_INSN_MACRO_MOV 0x80000001
+#define NIOS2_INSN_MACRO_MOVI 0x80000002
+#define NIOS2_INSN_MACRO_MOVIA 0x80000004
+
+#define NIOS2_INSN_RELAXABLE 0x40000000
+#define NIOS2_INSN_UBRANCH 0x00000010
+#define NIOS2_INSN_CBRANCH 0x00000020
+#define NIOS2_INSN_CALL 0x00000040
+
+#define NIOS2_INSN_ADDI 0x00000080
+#define NIOS2_INSN_ANDI 0x00000100
+#define NIOS2_INSN_ORI 0x00000200
+#define NIOS2_INSN_XORI 0x00000400
+
+
+
+/* Associates a register name ($6) with a 5-bit index (eg 6) */
+struct nios2_reg
+{
+ const char *name;
+ const int index;
+};
+
+
+/* -------------------------------------------------------------------------
+ Bitfield masks for New Jersey instructions
+ -------------------------------------------------------------------------*/
+
+/* These are bit masks and shift counts to use to access the various
+ fields of an instruction. */
+
+/* Macros for getting and setting an instruction field */
+#define GET_INSN_FIELD(X, i) ((i) & OP_MASK_##X) >> OP_SH_##X
+#define SET_INSN_FIELD(X, i, j) (i) = ((i) &~ (OP_MASK_##X)) | ((j) << OP_SH_##X)
+
+
+/*
+ We include the auto-generated file nios2-isa.h and define the mask
+ and shifts below in terms of those in nios2-isa.h. This ensures
+ that the binutils and hardware are always in sync
+*/
+
+#include "nios2-isa.h"
+
+#define OP_MASK_OP (IW_OP_MASK << IW_OP_LSB)
+#define OP_SH_OP IW_OP_LSB
+
+
+/* Masks and shifts for I-type instructions */
+
+#define OP_MASK_IOP (IW_OP_MASK << IW_OP_LSB)
+#define OP_SH_IOP IW_OP_LSB
+
+#define OP_MASK_IMM16 (IW_IMM16_MASK << IW_IMM16_LSB)
+#define OP_SH_IMM16 IW_IMM16_LSB
+
+#define OP_MASK_IRD (IW_B_MASK << IW_B_LSB) // the same as T for I-type
+#define OP_SH_IRD IW_B_LSB
+
+#define OP_MASK_IRT (IW_B_MASK << IW_B_LSB)
+#define OP_SH_IRT IW_B_LSB
+
+#define OP_MASK_IRS (IW_A_MASK << IW_A_LSB)
+#define OP_SH_IRS IW_A_LSB
+
+/* Masks and shifts for R-type instructions */
+
+#define OP_MASK_ROP (IW_OP_MASK << IW_OP_LSB)
+#define OP_SH_ROP IW_OP_LSB
+
+#define OP_MASK_ROPX (IW_OPX_MASK << IW_OPX_LSB)
+#define OP_SH_ROPX IW_OPX_LSB
+
+#define OP_MASK_RRD (IW_C_MASK << IW_C_LSB)
+#define OP_SH_RRD IW_C_LSB
+
+#define OP_MASK_RRT (IW_B_MASK << IW_B_LSB)
+#define OP_SH_RRT IW_B_LSB
+
+#define OP_MASK_RRS (IW_A_MASK << IW_A_LSB)
+#define OP_SH_RRS IW_A_LSB
+
+/* Masks and shifts for J-type instructions */
+
+#define OP_MASK_JOP (IW_OP_MASK << IW_OP_LSB)
+#define OP_SH_JOP IW_OP_LSB
+
+#define OP_MASK_IMM26 (IW_IMM26_MASK << IW_IMM26_LSB)
+#define OP_SH_IMM26 IW_IMM26_LSB
+
+/* Masks and shifts for CTL instructions */
+
+#define OP_MASK_RCTL 0x000007c0
+#define OP_SH_RCTL 6
+
+/* break instruction imm5 field */
+#define OP_MASK_TRAP_IMM5 0x000007c0
+#define OP_SH_TRAP_IMM5 6
+
+/* instruction imm5 field */
+#define OP_MASK_IMM5 (IW_SHIFT_IMM5_MASK << IW_SHIFT_IMM5_LSB)
+#define OP_SH_IMM5 IW_SHIFT_IMM5_LSB
+
+/* cache operation fields (type j,i(s)) */
+#define OP_MASK_CACHE_OPX (IW_B_MASK << IW_B_LSB)
+#define OP_SH_CACHE_OPX IW_B_LSB
+#define OP_MASK_CACHE_RRS (IW_A_MASK << IW_A_LSB)
+#define OP_SH_CACHE_RRS IW_A_LSB
+
+/* custom instruction masks */
+#define OP_MASK_CUSTOM_A 0x00010000
+#define OP_SH_CUSTOM_A 16
+
+#define OP_MASK_CUSTOM_B 0x00008000
+#define OP_SH_CUSTOM_B 15
+
+#define OP_MASK_CUSTOM_C 0x00004000
+#define OP_SH_CUSTOM_C 14
+
+#define OP_MASK_CUSTOM_N 0x00003fc0
+#define OP_SH_CUSTOM_N 6
+#define OP_MAX_CUSTOM_N 255
+
+/*
+ The following macros define the opcode matches for each
+ instruction
+ code & OP_MASK_INST == OP_MATCH_INST
+ */
+
+/* OP instruction matches */
+#define OP_MATCH_ADDI OP_ADDI
+#define OP_MATCH_ANDHI OP_ANDHI
+#define OP_MATCH_ANDI OP_ANDI
+#define OP_MATCH_BEQ OP_BEQ
+#define OP_MATCH_BGE OP_BGE
+#define OP_MATCH_BGEU OP_BGEU
+#define OP_MATCH_BLT OP_BLT
+#define OP_MATCH_BLTU OP_BLTU
+#define OP_MATCH_BNE OP_BNE
+#define OP_MATCH_BR OP_BR
+#define OP_MATCH_FLUSHD OP_FLUSHD
+#define OP_MATCH_FLUSHDA OP_FLUSHDA
+#define OP_MATCH_INITD OP_INITD
+#define OP_MATCH_CALL OP_CALL
+#define OP_MATCH_CMPEQI OP_CMPEQI
+#define OP_MATCH_CMPGEI OP_CMPGEI
+#define OP_MATCH_CMPGEUI OP_CMPGEUI
+#define OP_MATCH_CMPLTI OP_CMPLTI
+#define OP_MATCH_CMPLTUI OP_CMPLTUI
+#define OP_MATCH_CMPNEI OP_CMPNEI
+#define OP_MATCH_JMPI OP_JMPI
+#define OP_MATCH_LDB OP_LDB
+#define OP_MATCH_LDBIO OP_LDBIO
+#define OP_MATCH_LDBU OP_LDBU
+#define OP_MATCH_LDBUIO OP_LDBUIO
+#define OP_MATCH_LDH OP_LDH
+#define OP_MATCH_LDHIO OP_LDHIO
+#define OP_MATCH_LDHU OP_LDHU
+#define OP_MATCH_LDHUIO OP_LDHUIO
+#define OP_MATCH_LDW OP_LDW
+#define OP_MATCH_LDWIO OP_LDWIO
+#define OP_MATCH_MULI OP_MULI
+#define OP_MATCH_OPX OP_OPX
+#define OP_MATCH_ORHI OP_ORHI
+#define OP_MATCH_ORI OP_ORI
+#define OP_MATCH_STB OP_STB
+#define OP_MATCH_STBIO OP_STBIO
+#define OP_MATCH_STH OP_STH
+#define OP_MATCH_STHIO OP_STHIO
+#define OP_MATCH_STW OP_STW
+#define OP_MATCH_STWIO OP_STWIO
+#define OP_MATCH_CUSTOM OP_CUSTOM
+#define OP_MATCH_XORHI OP_XORHI
+#define OP_MATCH_XORI OP_XORI
+#define OP_MATCH_OPX OP_OPX
+
+
+
+/* OPX instruction values */
+#define OP_MATCH_ADD ((OPX_ADD << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_AND ((OPX_AND << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_BREAK ((0x1e << 17) | (OPX_BREAK << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_BRET ((0xf0000000) | (OPX_BRET << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_CALLR ((0x1f << 17) | (OPX_CALLR << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_CMPEQ ((OPX_CMPEQ << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_CMPGE ((OPX_CMPGE << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_CMPGEU ((OPX_CMPGEU << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_CMPLT ((OPX_CMPLT << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_CMPLTU ((OPX_CMPLTU << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_CMPNE ((OPX_CMPNE << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_DIV ((OPX_DIV << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_DIVU ((OPX_DIVU << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_JMP ((OPX_JMP << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_MUL ((OPX_MUL << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_MULXSS ((OPX_MULXSS << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_MULXSU ((OPX_MULXSU << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_MULXUU ((OPX_MULXUU << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_NEXTPC ((OPX_NEXTPC << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_NOR ((OPX_NOR << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_OR ((OPX_OR << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_RDCTL ((OPX_RDCTL << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_RET ((0xf8000000) | (OPX_RET << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_ROL ((OPX_ROL << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_ROLI ((OPX_ROLI << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_ROR ((OPX_ROR << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_SLL ((OPX_SLL << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_SLLI ((OPX_SLLI << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_SRA ((OPX_SRA << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_SRAI ((OPX_SRAI << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_SRL ((OPX_SRL << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_SRLI ((OPX_SRLI << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_SUB ((OPX_SUB << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_SYNC ((OPX_SYNC << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_TRAP ((0x1d << 17) | (OPX_TRAP << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_ERET ((0xe8000000) | (OPX_ERET << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_WRCTL ((OPX_WRCTL << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_XOR ((OPX_XOR << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_FLUSHI ((OPX_FLUSHI << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_FLUSHP ((OPX_FLUSHP << IW_OPX_LSB) | (OP_OPX))
+#define OP_MATCH_INITI ((OPX_INITI << IW_OPX_LSB) | (OP_OPX))
+
+/*
+ Some unusual op masks
+*/
+#define OP_MASK_BREAK ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP) & 0xfffff03f)
+#define OP_MASK_CALLR ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
+#define OP_MASK_JMP ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
+#define OP_MASK_SYNC ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
+#define OP_MASK_TRAP ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP) & 0xfffff83f)
+#define OP_MASK_WRCTL ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP)) /*& 0xfffff83f */
+#define OP_MASK_NEXTPC ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
+#define OP_MASK_FLUSHI ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
+#define OP_MASK_INITI ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
+
+#define OP_MASK_ROLI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
+#define OP_MASK_SLLI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
+#define OP_MASK_SRAI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
+#define OP_MASK_SRLI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
+#define OP_MASK_RDCTL ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP)) /*& 0xfffff83f */
+
+#ifndef OP_MASK
+#define OP_MASK 0xffffffff
+#endif
+
+/* These are the data structures we use to hold the instruction information */
+
+extern const struct nios2_opcode nios2_builtin_opcodes[];
+extern const int bfd_nios2_num_builtin_opcodes;
+extern struct nios2_opcode *nios2_opcodes;
+extern int bfd_nios2_num_opcodes;
+
+/* These are the data structures used to hold the operand parsing information */
+//extern const struct nios2_arg_parser nios2_arg_parsers[];
+//extern struct nios2_arg_parser* nios2_arg_parsers;
+//extern const int nios2_num_builtin_arg_parsers;
+//extern int nios2_num_arg_parsers;
+
+/* These are the data structures used to hold the register information */
+extern const struct nios2_reg nios2_builtin_regs[];
+extern struct nios2_reg *nios2_regs;
+extern const int nios2_num_builtin_regs;
+extern int nios2_num_regs;
+
+/* Machine-independent macro for number of opcodes */
+
+#define NUMOPCODES bfd_nios2_num_opcodes
+#define NUMREGISTERS nios2_num_regs;
+
+/* these are used in disassembly to get the correct register names */
+#define NUMREGNAMES 32
+#define NUMCTLREGNAMES 32
+#define CTLREGBASE 42
+#define COPROCREGBASE 83
+#define NUMCOPROCREGNAMES 32
+
+
+/* this is made extern so that the assembler can use it to find out
+ what instruction caused an error */
+extern const struct nios2_opcode *nios2_find_opcode_hash (unsigned long);
+
+/* overflow message strings used in the assembler */
+extern char *overflow_msgs[];
+
+#endif // _NIOS2_H
diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am
index ebd252f..a7ca06b 100644
--- a/opcodes/Makefile.am
+++ b/opcodes/Makefile.am
@@ -146,6 +146,13 @@ CFILES = \
mt-dis.c \
mt-ibld.c \
mt-opc.c \
+ nios2-opc.c \
+ nios2-dis.c \
+ ms1-asm.c \
+ ms1-desc.c \
+ ms1-dis.c \
+ ms1-ibld.c \
+ ms1-opc.c \
ns32k-dis.c \
openrisc-asm.c \
openrisc-desc.c \
@@ -281,6 +288,8 @@ ALL_MACHINES = \
mt-dis.lo \
mt-ibld.lo \
mt-opc.lo \
+ nios2-opc.lo \
+ nios2-dis.lo \
ns32k-dis.lo \
openrisc-asm.lo \
openrisc-desc.lo \
@@ -980,6 +989,13 @@ mt-opc.lo: mt-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
mt-desc.h $(INCDIR)/opcode/cgen-bitset.h $(INCDIR)/opcode/cgen.h \
$(INCDIR)/symcat.h $(INCDIR)/opcode/cgen-bitset.h mt-opc.h \
$(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h $(INCDIR)/safe-ctype.h
+nios2-opc.lo: nios2-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/opcode/nios2.h
+nios2-dis.lo: nios2-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/nios2.h \
+ opintl.h $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/nios2.h $(INCDIR)/elf/reloc-macros.h
ns32k-dis.lo: ns32k-dis.c $(BFD_H) $(INCDIR)/ansidecl.h \
$(INCDIR)/symcat.h sysdep.h config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/opcode/ns32k.h \
diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in
index 85003e6..9e3baae 100644
--- a/opcodes/Makefile.in
+++ b/opcodes/Makefile.in
@@ -360,6 +360,8 @@ CFILES = \
mt-dis.c \
mt-ibld.c \
mt-opc.c \
+ nios2-opc.c \
+ nios2-dis.c \
ns32k-dis.c \
openrisc-asm.c \
openrisc-desc.c \
@@ -495,6 +497,8 @@ ALL_MACHINES = \
mt-dis.lo \
mt-ibld.lo \
mt-opc.lo \
+ nios2-opc.lo \
+ nios2-dis.lo \
ns32k-dis.lo \
openrisc-asm.lo \
openrisc-desc.lo \
@@ -1517,6 +1521,13 @@ mt-opc.lo: mt-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
mt-desc.h $(INCDIR)/opcode/cgen-bitset.h $(INCDIR)/opcode/cgen.h \
$(INCDIR)/symcat.h $(INCDIR)/opcode/cgen-bitset.h mt-opc.h \
$(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h $(INCDIR)/safe-ctype.h
+nios2-opc.lo: nios2-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/opcode/nios2.h
+nios2-dis.lo: nios2-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/nios2.h \
+ opintl.h $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/nios2.h $(INCDIR)/elf/reloc-macros.h
ns32k-dis.lo: ns32k-dis.c $(BFD_H) $(INCDIR)/ansidecl.h \
$(INCDIR)/symcat.h sysdep.h config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/opcode/ns32k.h \
diff --git a/opcodes/configure b/opcodes/configure
index 8e3e27e..a28cc46 100755
--- a/opcodes/configure
+++ b/opcodes/configure
@@ -6561,6 +6561,7 @@ if test x${all_targets} = xfalse ; then
bfd_mn10300_arch) ta="$ta m10300-dis.lo m10300-opc.lo" ;;
bfd_mt_arch) ta="$ta mt-asm.lo mt-desc.lo mt-dis.lo mt-ibld.lo mt-opc.lo" using_cgen=yes ;;
bfd_msp430_arch) ta="$ta msp430-dis.lo" ;;
+ bfd_nios2_arch) ta="$ta nios2-opc.lo nios2-dis.lo" ;;
bfd_ns32k_arch) ta="$ta ns32k-dis.lo" ;;
bfd_openrisc_arch) ta="$ta openrisc-asm.lo openrisc-desc.lo openrisc-dis.lo openrisc-ibld.lo openrisc-opc.lo" using_cgen=yes ;;
bfd_or32_arch) ta="$ta or32-dis.lo or32-opc.lo" using_cgen=yes ;;
diff --git a/opcodes/configure.in b/opcodes/configure.in
index d937784..c9df814 100644
--- a/opcodes/configure.in
+++ b/opcodes/configure.in
@@ -190,6 +190,7 @@ if test x${all_targets} = xfalse ; then
bfd_mn10300_arch) ta="$ta m10300-dis.lo m10300-opc.lo" ;;
bfd_mt_arch) ta="$ta mt-asm.lo mt-desc.lo mt-dis.lo mt-ibld.lo mt-opc.lo" using_cgen=yes ;;
bfd_msp430_arch) ta="$ta msp430-dis.lo" ;;
+ bfd_nios2_arch) ta="$ta nios2-opc.lo nios2-dis.lo" ;;
bfd_ns32k_arch) ta="$ta ns32k-dis.lo" ;;
bfd_openrisc_arch) ta="$ta openrisc-asm.lo openrisc-desc.lo openrisc-dis.lo openrisc-ibld.lo openrisc-opc.lo" using_cgen=yes ;;
bfd_or32_arch) ta="$ta or32-dis.lo or32-opc.lo" using_cgen=yes ;;
diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c
index ca28f56..dfacbb9 100644
--- a/opcodes/disassemble.c
+++ b/opcodes/disassemble.c
@@ -80,6 +80,7 @@
#define ARCH_xtensa
#define ARCH_z80
#define ARCH_z8k
+#define ARCH_nios2
#define INCLUDE_SHMEDIA
#endif
@@ -424,6 +425,14 @@ disassembler (abfd)
disassemble = print_insn_iq2000;
break;
#endif
+#ifdef ARCH_nios2
+ case bfd_arch_nios2:
+ if (bfd_big_endian (abfd))
+ disassemble = print_insn_big_nios2;
+ else
+ disassemble = print_insn_little_nios2;
+ break;
+#endif
#ifdef ARCH_m32c
case bfd_arch_m32c:
disassemble = print_insn_m32c;
diff --git a/opcodes/nios2-dis.c b/opcodes/nios2-dis.c
new file mode 100644
index 0000000..ac9eb0d
--- /dev/null
+++ b/opcodes/nios2-dis.c
@@ -0,0 +1,462 @@
+/* nios2-dis.c -- Altera New Jersey disassemble routines.
+
+ Copyright (C) 2003
+ by Nigel Gray (ngray@altera.com).
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "dis-asm.h"
+#include "opcode/nios2.h"
+
+/* No symbol table is available when this code runs out in an embedded
+ system as when it is used for disassembler support in a monitor. */
+
+#if !defined(EMBEDDED_ENV)
+#define SYMTAB_AVAILABLE 1
+#include "elf-bfd.h"
+#include "elf/nios2.h"
+#endif
+
+/* length of New Jersey instruction in bytes */
+#define INSNLEN 4
+
+/* helper function prototypes */
+static int nios2_disassemble (bfd_vma, unsigned long, disassemble_info *);
+static void nios2_init_opcode_hash (void);
+
+
+static int nios2_print_insn_arg (const char *argptr, unsigned long opcode,
+ bfd_vma address, disassemble_info * info);
+
+
+/* print_insn_nios2 is the main disassemble function for New Jersey.
+ The function diassembler(abfd) (source in disassemble.c) returns a
+ pointer to this either print_insn_big_nios2 or
+ print_insn_little_nios2, which in turn call this function, when the
+ bfd machine type is New Jersey. print_insn_nios2 reads the
+ instruction word at the address given, and prints the disassembled
+ instruction on the stream info->stream using info->fprintf_func. */
+
+static int
+print_insn_nios2 (bfd_vma address, disassemble_info * info,
+ enum bfd_endian endianness)
+{
+ /* buffer into which the instruction bytes are written */
+ bfd_byte buffer[INSNLEN];
+ /* used to indicate return status from function calls */
+ int status;
+
+ assert (info != NULL);
+
+ status = (*info->read_memory_func) (address, buffer, INSNLEN, info);
+ if (status == 0)
+ {
+ unsigned long insn;
+ if (endianness == BFD_ENDIAN_BIG)
+ insn = (unsigned long) bfd_getb32 (buffer);
+ else
+ insn = (unsigned long) bfd_getl32 (buffer);
+ status = nios2_disassemble (address, insn, info);
+ }
+ else
+ {
+ (*info->memory_error_func) (status, address, info);
+ status = -1;
+ }
+ return status;
+}
+
+int
+print_insn_big_nios2 (bfd_vma address, disassemble_info * info)
+{
+ return print_insn_nios2 (address, info, BFD_ENDIAN_BIG);
+}
+
+int
+print_insn_little_nios2 (bfd_vma address, disassemble_info * info)
+{
+ return print_insn_nios2 (address, info, BFD_ENDIAN_LITTLE);
+}
+
+/* Data structures used by the opcode hash table */
+
+typedef struct _nios2_opcode_hash
+{
+ const struct nios2_opcode *opcode;
+ struct _nios2_opcode_hash *next;
+} nios2_opcode_hash;
+
+static bfd_boolean nios2_hash_init = 0;
+static nios2_opcode_hash *nios2_hash[(OP_MASK_OP) + 1];
+
+/* separate hash table for pseudo-ops */
+static nios2_opcode_hash *nios2_ps_hash[(OP_MASK_OP) + 1];
+
+/* Function to initialize the opcode hash table */
+
+void
+nios2_init_opcode_hash ()
+{
+ unsigned int i;
+ register const struct nios2_opcode *op;
+ nios2_opcode_hash *tmp_hash;
+
+ for (i = 0; i <= OP_MASK_OP; ++i)
+ {
+ nios2_hash[0] = NULL;
+ }
+ for (i = 0; i <= OP_MASK_OP; i++)
+ {
+ for (op = nios2_opcodes; op < &nios2_opcodes[NUMOPCODES]; op++)
+ {
+ if ((op->pinfo & NIOS2_INSN_MACRO) == NIOS2_INSN_MACRO)
+ {
+ if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP) &&
+ (op->
+ pinfo & (NIOS2_INSN_MACRO_MOV | NIOS2_INSN_MACRO_MOVI) &
+ 0x7fffffff) != 0)
+ {
+ tmp_hash = nios2_ps_hash[i];
+ if (tmp_hash == NULL)
+ {
+ tmp_hash =
+ (nios2_opcode_hash *)
+ malloc (sizeof (nios2_opcode_hash));
+ nios2_ps_hash[i] = tmp_hash;
+ }
+ else
+ {
+ while (tmp_hash->next != NULL)
+ tmp_hash = tmp_hash->next;
+ tmp_hash->next =
+ (nios2_opcode_hash *)
+ malloc (sizeof (nios2_opcode_hash));
+ tmp_hash = tmp_hash->next;
+ }
+ if (tmp_hash == NULL)
+ {
+ fprintf (stderr,
+ "error allocating memory...broken disassembler\n");
+ abort ();
+ }
+ tmp_hash->opcode = op;
+ tmp_hash->next = NULL;
+ }
+ }
+ else if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
+ {
+ tmp_hash = nios2_hash[i];
+ if (tmp_hash == NULL)
+ {
+ tmp_hash =
+ (nios2_opcode_hash *) malloc (sizeof (nios2_opcode_hash));
+ nios2_hash[i] = tmp_hash;
+ }
+ else
+ {
+ while (tmp_hash->next != NULL)
+ tmp_hash = tmp_hash->next;
+ tmp_hash->next =
+ (nios2_opcode_hash *) malloc (sizeof (nios2_opcode_hash));
+ tmp_hash = tmp_hash->next;
+ }
+ if (tmp_hash == NULL)
+ {
+ fprintf (stderr,
+ "error allocating memory...broken disassembler\n");
+ abort ();
+ }
+ tmp_hash->opcode = op;
+ tmp_hash->next = NULL;
+ }
+ }
+ }
+ nios2_hash_init = 1;
+#ifdef DEBUG_HASHTABLE
+ for (i = 0; i <= OP_MASK_OP; ++i)
+ {
+ printf ("index: 0x%02X ops: ", i);
+ tmp_hash = nios2_hash[i];
+ if (tmp_hash != NULL)
+ {
+ while (tmp_hash != NULL)
+ {
+ printf ("%s ", tmp_hash->opcode->name);
+ tmp_hash = tmp_hash->next;
+ }
+ }
+ printf ("\n");
+ }
+
+ for (i = 0; i <= OP_MASK_OP; ++i)
+ {
+ printf ("index: 0x%02X ops: ", i);
+ tmp_hash = nios2_ps_hash[i];
+ if (tmp_hash != NULL)
+ {
+ while (tmp_hash != NULL)
+ {
+ printf ("%s ", tmp_hash->opcode->name);
+ tmp_hash = tmp_hash->next;
+ }
+ }
+ printf ("\n");
+ }
+#endif
+}
+
+/* Function which returns a pointer to an nios2_opcode struct for
+ a given instruction opcode, or NULL if there is an error */
+
+const struct nios2_opcode *
+nios2_find_opcode_hash (unsigned long opcode)
+{
+ nios2_opcode_hash *entry;
+
+ /* Build a hash table to shorten the search time. */
+ if (!nios2_hash_init)
+ {
+ nios2_init_opcode_hash ();
+ }
+
+ /* first look in the pseudo-op hashtable */
+ entry = nios2_ps_hash[(opcode >> OP_SH_OP) & OP_MASK_OP];
+
+ /* look for a match and if we get one, this is the instruction we decode */
+ while (entry != NULL)
+ {
+ if ((entry->opcode->match) == (opcode & entry->opcode->mask))
+ return entry->opcode;
+ else
+ entry = entry->next;
+ }
+
+ /* if we haven't yet returned, then we need to look in the main
+ hashtable */
+ entry = nios2_hash[(opcode >> OP_SH_OP) & OP_MASK_OP];
+
+ if (entry == NULL)
+ return NULL;
+
+
+ while (entry != NULL)
+ {
+ if ((entry->opcode->match) == (opcode & entry->opcode->mask))
+ return entry->opcode;
+ else
+ entry = entry->next;
+ }
+
+ return NULL;
+}
+
+/* nios2_disassemble does all the work of disassembling a New Jersey
+ instruction opcode */
+
+int
+nios2_disassemble (bfd_vma address, unsigned long opcode,
+ disassemble_info * info)
+{
+ const struct nios2_opcode *op;
+ const char *argstr;
+
+ info->bytes_per_line = INSNLEN;
+ info->bytes_per_chunk = INSNLEN;
+ info->display_endian = info->endian;
+ info->insn_info_valid = 1;
+ info->branch_delay_insns = 0;
+ info->data_size = 0;
+ info->insn_type = dis_nonbranch;
+ info->target = 0;
+ info->target2 = 0;
+
+ /* Find the major opcode and use this to disassemble
+ the instruction and its arguments */
+ op = nios2_find_opcode_hash (opcode);
+
+ if (op != NULL)
+ {
+ bfd_boolean is_nop = FALSE;
+ if (op->pinfo == NIOS2_INSN_MACRO_MOV)
+ {
+ /* check for mov r0, r0 and if it is
+ change to nop */
+ int dst, src;
+ dst = GET_INSN_FIELD (RRD, opcode);
+ src = GET_INSN_FIELD (RRS, opcode);
+ if (dst == 0 && src == 0)
+ {
+ (*info->fprintf_func) (info->stream, "nop");
+ is_nop = TRUE;
+ }
+ else
+ {
+ (*info->fprintf_func) (info->stream, "%s", op->name);
+ }
+ }
+ else
+ {
+ (*info->fprintf_func) (info->stream, "%s", op->name);
+ }
+
+ if (!is_nop)
+ {
+ argstr = op->args;
+ if (argstr != NULL && *argstr != '\0')
+ {
+ (*info->fprintf_func) (info->stream, "\t");
+ while (*argstr != '\0')
+ {
+ nios2_print_insn_arg (argstr, opcode, address, info);
+ ++argstr;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Handle undefined instructions. */
+ info->insn_type = dis_noninsn;
+ (*info->fprintf_func) (info->stream, "0x%x", (unsigned int) opcode);
+ }
+ // this tells the caller how far to advance the program counter
+ return INSNLEN;
+}
+
+/* The function nios2_print_insn_arg uses the character pointed
+ to by argptr to determine how it print the next token or separator
+ character in the arguments to an instruction */
+int
+nios2_print_insn_arg (const char *argptr,
+ unsigned long opcode, bfd_vma address,
+ disassemble_info * info)
+{
+ unsigned long i = 0;
+ unsigned long reg_base;
+
+ assert (argptr != NULL);
+ assert (info != NULL);
+
+ switch (*argptr)
+ {
+ case ',':
+ case '(':
+ case ')':
+ (*info->fprintf_func) (info->stream, "%c", *argptr);
+ break;
+ case 'd':
+ i = GET_INSN_FIELD (RRD, opcode);
+
+ if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
+ && GET_INSN_FIELD (CUSTOM_C, opcode) == 0)
+ reg_base = COPROCREGBASE;
+ else
+ reg_base = 0;
+
+ if (i < NUMREGNAMES)
+ (*info->fprintf_func) (info->stream, "%s",
+ nios2_regs[i + reg_base].name);
+ else
+ (*info->fprintf_func) (info->stream, "unknown");
+ break;
+ case 's':
+ i = GET_INSN_FIELD (RRS, opcode);
+
+ if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
+ && GET_INSN_FIELD (CUSTOM_A, opcode) == 0)
+ reg_base = COPROCREGBASE;
+ else
+ reg_base = 0;
+
+ if (i < NUMREGNAMES)
+ (*info->fprintf_func) (info->stream, "%s",
+ nios2_regs[i + reg_base].name);
+ else
+ (*info->fprintf_func) (info->stream, "unknown");
+ break;
+ case 't':
+ i = GET_INSN_FIELD (RRT, opcode);
+
+ if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
+ && GET_INSN_FIELD (CUSTOM_B, opcode) == 0)
+ reg_base = COPROCREGBASE;
+ else
+ reg_base = 0;
+
+ if (i < NUMREGNAMES)
+ (*info->fprintf_func) (info->stream, "%s",
+ nios2_regs[i + reg_base].name);
+ else
+ (*info->fprintf_func) (info->stream, "unknown");
+ break;
+ case 'i':
+ /* 16-bit signed immediate */
+ i = (signed) (GET_INSN_FIELD (IMM16, opcode) << 16) >> 16;
+ (*info->fprintf_func) (info->stream, "%d", (int) i);
+ break;
+ case 'u':
+ /* 16-bit unsigned immediate */
+ i = GET_INSN_FIELD (IMM16, opcode);
+ (*info->fprintf_func) (info->stream, "%d", (int) i);
+ break;
+ case 'o':
+ /* 16-bit signed immediate address offset */
+ i = (signed) (GET_INSN_FIELD (IMM16, opcode) << 16) >> 16;
+ address = address + 4 + i; /* NG changed to byte offset 1/9/03 */
+ (*info->print_address_func) (address, info);
+ break;
+ case 'p':
+ /* 5-bit unsigned immediate */
+ i = GET_INSN_FIELD (CACHE_OPX, opcode);
+ (*info->fprintf_func) (info->stream, "%d", (int) i);
+ break;
+ case 'j':
+ /* 5-bit unsigned immediate */
+ i = GET_INSN_FIELD (IMM5, opcode);
+ (*info->fprintf_func) (info->stream, "%d", (int) i);
+ break;
+ case 'l':
+ /* 8-bit unsigned immediate */
+ /* FIXME - not yet implemented */
+ i = GET_INSN_FIELD (CUSTOM_N, opcode);
+ (*info->fprintf_func) (info->stream, "%u", (int) i);
+ break;
+ case 'm':
+ /* 26-bit unsigned immediate */
+ i = GET_INSN_FIELD (IMM26, opcode);
+ /* this translates to an address because its only used in call instructions */
+ address = (address & 0xf0000000) | (i << 2);
+ (*info->print_address_func) (address, info);
+ break;
+ case 'c':
+ i = GET_INSN_FIELD (IMM5, opcode); /* ctrl register index */
+ (*info->fprintf_func) (info->stream, "%s",
+ nios2_regs[CTLREGBASE + i].name);
+ break;
+ case 'b':
+ i = GET_INSN_FIELD (IMM5, opcode);
+ (*info->fprintf_func) (info->stream, "%d", (int) i);
+ break;
+ default:
+ (*info->fprintf_func) (info->stream, "unknown");
+ break;
+ }
+ return 0;
+}
diff --git a/opcodes/nios2-opc.c b/opcodes/nios2-opc.c
new file mode 100644
index 0000000..c860207
--- /dev/null
+++ b/opcodes/nios2-opc.c
@@ -0,0 +1,320 @@
+/* nios2-opc.c -- Altera New Jersey opcode list.
+
+ Copyright (C) 2003
+ by Nigel Gray (ngray@altera.com).
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "opcode/nios2.h"
+
+/* Register string table */
+
+const struct nios2_reg nios2_builtin_regs[] = {
+ {"zero", 0},
+ {"at", 1}, // assembler temporary
+ {"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},
+ {"et", 24},
+ {"bt", 25},
+ {"gp", 26}, /* global pointer */
+ {"sp", 27}, /* stack pointer */
+ {"fp", 28}, /* frame pointer */
+ {"ea", 29}, /* exception return address */
+ {"ba", 30}, /* breakpoint return address */
+ {"ra", 31}, /* return address */
+
+ /* alternative names for special registers */
+ {"r0", 0},
+ {"r1", 1},
+ {"r24", 24},
+ {"r25", 25},
+ {"r26", 26},
+ {"r27", 27},
+ {"r28", 28},
+ {"r29", 29},
+ {"r30", 30},
+ {"r31", 31},
+
+ /* control register names */
+ {"status", 0},
+ {"estatus", 1},
+ {"bstatus", 2},
+ {"ienable", 3},
+ {"ipending", 4},
+ {"cpuid", 5},
+ {"ctl6", 6},
+ {"ctl7", 7},
+ {"pteaddr", 8},
+ {"tlbacc", 9},
+ {"tlbmisc", 10},
+ {"fstatus", 11},
+ {"ctl12", 12},
+ {"ctl13", 13},
+ {"ctl14", 14},
+ {"ctl15", 15},
+ {"ctl16", 16},
+ {"ctl17", 17},
+ {"ctl18", 18},
+ {"ctl19", 19},
+ {"ctl20", 20},
+ {"ctl21", 21},
+ {"ctl22", 22},
+ {"ctl23", 23},
+ {"ctl24", 24},
+ {"ctl25", 25},
+ {"ctl26", 26},
+ {"ctl27", 27},
+ {"ctl28", 28},
+ {"ctl29", 29},
+ {"ctl30", 30},
+ {"ctl31", 31},
+
+ /* alternative names for special control registers */
+ {"ctl0", 0},
+ {"ctl1", 1},
+ {"ctl2", 2},
+ {"ctl3", 3},
+ {"ctl4", 4},
+ {"ctl5", 5},
+ {"ctl8", 8},
+ {"ctl9", 9},
+ {"ctl10", 10},
+ {"ctl11", 11},
+
+ /* coprocessor register names */
+ {"c0", 0},
+ {"c1", 1},
+ {"c2", 2},
+ {"c3", 3},
+ {"c4", 4},
+ {"c5", 5},
+ {"c6", 6},
+ {"c7", 7},
+ {"c8", 8},
+ {"c9", 9},
+ {"c10", 10},
+ {"c11", 11},
+ {"c12", 12},
+ {"c13", 13},
+ {"c14", 14},
+ {"c15", 15},
+ {"c16", 16},
+ {"c17", 17},
+ {"c18", 18},
+ {"c19", 19},
+ {"c20", 20},
+ {"c21", 21},
+ {"c22", 22},
+ {"c23", 23},
+ {"c24", 24},
+ {"c25", 25},
+ {"c26", 26},
+ {"c27", 27},
+ {"c28", 28},
+ {"c29", 29},
+ {"c30", 30},
+ {"c31", 31},
+};
+
+#define NIOS2_NUM_REGS \
+ ((sizeof nios2_builtin_regs) / (sizeof (nios2_builtin_regs[0])))
+const int nios2_num_builtin_regs = NIOS2_NUM_REGS;
+
+/* const removed from the following to allow for dynamic extensions to the
+ * built-in instruction set. */
+struct nios2_reg *nios2_regs = (struct nios2_reg *) nios2_builtin_regs;
+int nios2_num_regs = NIOS2_NUM_REGS;
+#undef NIOS2_NUM_REGS
+
+/* overflow message string templates */
+
+char *overflow_msgs[] = {
+ "call target address 0x%08x out of range 0x%08x to 0x%08x",
+ "branch offset %d out of range %d to %d",
+ "%s offset %d out of range %d to %d",
+ "immediate value %d out of range %d to %d",
+ "immediate value %u out of range %u to %u",
+ "immediate value %u out of range %u to %u",
+ "custom instruction opcode %u out of range %u to %u",
+};
+
+
+
+/*--------------------------------------------------------------------------------
+ This is the opcode table used by the New Jersey GNU as, disassembler and GDB
+ --------------------------------------------------------------------------------*/
+
+/*
+ The following letters can appear in the args field of the nios2_opcode
+ structure:
+
+ c - a 5-bit control register index or break opcode
+ d - a 5-bit destination register index
+ s - a 5-bit left source register index
+ t - a 5-bit right source register index
+ i - a 16-bit signed immediate
+ u - a 16-bit unsigned immediate
+
+ j - a 5-bit unsigned immediate
+ k - a 6-bit unsigned immediate
+ l - an 8-bit unsigned immediate
+ m - a 26-bit unsigned immediate
+*/
+
+/* *INDENT-OFF* */
+/* FIXME: Re-format for GNU standards */
+const struct nios2_opcode nios2_builtin_opcodes[] =
+{
+ /* name, args, args_test num_args, match, mask, pinfo */
+ {"add", "d,s,t", "d,s,t,E", 3, OP_MATCH_ADD, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"addi", "t,s,i", "t,s,i,E", 3, OP_MATCH_ADDI, OP_MASK_IOP, NIOS2_INSN_ADDI, signed_immed16_overflow },
+ {"subi", "t,s,i", "t,s,i,E", 3, OP_MATCH_ADDI, OP_MASK_IOP, NIOS2_INSN_MACRO, signed_immed16_overflow },
+ {"and", "d,s,t", "d,s,t,E", 3, OP_MATCH_AND, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"andhi", "t,s,u", "t,s,u,E", 3, OP_MATCH_ANDHI, OP_MASK_IOP, 0, unsigned_immed16_overflow },
+ {"andi", "t,s,u", "t,s,u,E", 3, OP_MATCH_ANDI, OP_MASK_IOP, NIOS2_INSN_ANDI, unsigned_immed16_overflow },
+ {"beq", "s,t,o", "s,t,o,E", 3, OP_MATCH_BEQ, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow },
+ {"bge", "s,t,o", "s,t,o,E", 3, OP_MATCH_BGE, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow },
+ {"bgeu", "s,t,o", "s,t,o,E", 3, OP_MATCH_BGEU, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow },
+ {"bgt", "s,t,o", "s,t,o,E", 3, OP_MATCH_BLT, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow },
+ {"bgtu", "s,t,o", "s,t,o,E", 3, OP_MATCH_BLTU, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow },
+ {"ble", "s,t,o", "s,t,o,E", 3, OP_MATCH_BGE, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow },
+ {"bleu", "s,t,o", "s,t,o,E", 3, OP_MATCH_BGEU, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow },
+ {"blt", "s,t,o", "s,t,o,E", 3, OP_MATCH_BLT, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow },
+ {"bltu", "s,t,o", "s,t,o,E", 3, OP_MATCH_BLTU, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow },
+ {"bne", "s,t,o", "s,t,o,E", 3, OP_MATCH_BNE, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow },
+ {"br", "o", "o,E", 1, OP_MATCH_BR, OP_MASK_IOP, NIOS2_INSN_UBRANCH, branch_target_overflow },
+ {"break", "b", "b,E", 1, OP_MATCH_BREAK, OP_MASK_BREAK, 0, no_overflow },
+ {"bret", "", "E", 0, OP_MATCH_BRET, OP_MASK, 0, no_overflow },
+ {"flushd", "i(s)", "i(s)E", 2, OP_MATCH_FLUSHD, OP_MASK_IOP, 0, signed_immed16_overflow },
+ {"flushda", "i(s)", "i(s)E", 2, OP_MATCH_FLUSHDA, OP_MASK_IOP, 0, signed_immed16_overflow },
+ {"flushi", "s", "s,E", 1, OP_MATCH_FLUSHI, OP_MASK_FLUSHI, 0, no_overflow },
+ {"flushp", "", "E", 0, OP_MATCH_FLUSHP, OP_MASK, 0, no_overflow },
+ {"initd", "i(s)", "i(s)E", 2, OP_MATCH_INITD, OP_MASK_IOP, 0, signed_immed16_overflow },
+ {"initi", "s", "s,E", 1, OP_MATCH_INITI, OP_MASK_INITI, 0, no_overflow },
+ {"call", "m", "m,E", 1, OP_MATCH_CALL, OP_MASK_IOP, NIOS2_INSN_CALL, call_target_overflow },
+ {"callr", "s", "s,E", 1, OP_MATCH_CALLR, OP_MASK_CALLR, 0, no_overflow },
+ {"cmpeq", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPEQ, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"cmpeqi", "t,s,i", "t,s,i,E", 3, OP_MATCH_CMPEQI, OP_MASK_IOP, 0, signed_immed16_overflow },
+ {"cmpge", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPGE, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"cmpgei", "t,s,i", "t,s,i,E", 3, OP_MATCH_CMPGEI, OP_MASK_IOP, 0, signed_immed16_overflow },
+ {"cmpgeu", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPGEU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"cmpgeui", "t,s,u", "t,s,u,E", 3, OP_MATCH_CMPGEUI, OP_MASK_IOP, 0, unsigned_immed16_overflow },
+ {"cmpgt", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPLT, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow },
+ {"cmpgti", "t,s,i", "t,s,i,E", 3, OP_MATCH_CMPGEI, OP_MASK_IOP, NIOS2_INSN_MACRO, signed_immed16_overflow },
+ {"cmpgtu", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPLTU, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow },
+ {"cmpgtui", "t,s,u", "t,s,u,E", 3, OP_MATCH_CMPGEUI, OP_MASK_IOP, NIOS2_INSN_MACRO, unsigned_immed16_overflow },
+ {"cmple", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPGE, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow },
+ {"cmplei", "t,s,i", "t,s,i,E", 3, OP_MATCH_CMPLTI, OP_MASK_IOP, NIOS2_INSN_MACRO, signed_immed16_overflow },
+ {"cmpleu", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPGEU, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow },
+ {"cmpleui", "t,s,u", "t,s,u,E", 3, OP_MATCH_CMPLTUI, OP_MASK_IOP, NIOS2_INSN_MACRO, unsigned_immed16_overflow },
+ {"cmplt", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPLT, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"cmplti", "t,s,i", "t,s,i,E", 3, OP_MATCH_CMPLTI, OP_MASK_IOP, 0, signed_immed16_overflow },
+ {"cmpltu", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPLTU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"cmpltui", "t,s,u", "t,s,u,E", 3, OP_MATCH_CMPLTUI, OP_MASK_IOP, 0, unsigned_immed16_overflow },
+ {"cmpne", "d,s,t", "d,s,t,E", 3, OP_MATCH_CMPNE, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"cmpnei", "t,s,i", "t,s,i,E", 3, OP_MATCH_CMPNEI, OP_MASK_IOP, 0, signed_immed16_overflow },
+ {"div", "d,s,t", "d,s,t,E", 3, OP_MATCH_DIV, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"divu", "d,s,t", "d,s,t,E", 3, OP_MATCH_DIVU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"jmp", "s", "s,E", 1, OP_MATCH_JMP, OP_MASK_JMP, 0, no_overflow },
+ {"jmpi", "m", "m,E", 1, OP_MATCH_JMPI, OP_MASK_IOP, 0, no_overflow },
+ {"ldb", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDB, OP_MASK_IOP, 0, address_offset_overflow },
+ {"ldbio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDBIO, OP_MASK_IOP, 0, address_offset_overflow },
+ {"ldbu", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDBU, OP_MASK_IOP, 0, address_offset_overflow },
+ {"ldbuio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDBUIO, OP_MASK_IOP, 0, address_offset_overflow },
+ {"ldh", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDH, OP_MASK_IOP, 0, address_offset_overflow },
+ {"ldhio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDHIO, OP_MASK_IOP, 0, address_offset_overflow },
+ {"ldhu", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDHU, OP_MASK_IOP, 0, address_offset_overflow },
+ {"ldhuio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDHUIO, OP_MASK_IOP, 0, address_offset_overflow },
+ {"ldw", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDW, OP_MASK_IOP, 0, address_offset_overflow },
+ {"ldwio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_LDWIO, OP_MASK_IOP, 0, address_offset_overflow },
+ {"mov", "d,s", "d,s,E", 2, OP_MATCH_ADD, OP_MASK_RRT|OP_MASK_ROPX|OP_MASK_ROP, NIOS2_INSN_MACRO_MOV, no_overflow },
+ {"movhi", "t,u", "t,u,E", 2, OP_MATCH_ORHI, OP_MASK_IRS|OP_MASK_IOP, NIOS2_INSN_MACRO_MOVI, unsigned_immed16_overflow },
+ {"movui", "t,u", "t,u,E", 2, OP_MATCH_ORI, OP_MASK_IRS|OP_MASK_IOP, NIOS2_INSN_MACRO_MOVI, unsigned_immed16_overflow },
+ {"movi", "t,i", "t,i,E", 2, OP_MATCH_ADDI, OP_MASK_IRS|OP_MASK_IOP, NIOS2_INSN_MACRO_MOVI, signed_immed16_overflow },
+ /* movia expands to two instructions so there is no mask or match */
+ {"movia", "t,o", "t,o,E", 2, OP_MATCH_ORHI, OP_MASK_IOP, NIOS2_INSN_MACRO_MOVIA, no_overflow },
+ {"mul", "d,s,t", "d,s,t,E", 3, OP_MATCH_MUL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"muli", "t,s,i", "t,s,i,E", 3, OP_MATCH_MULI, OP_MASK_IOP, 0, signed_immed16_overflow },
+ {"mulxss", "d,s,t", "d,s,t,E", 3, OP_MATCH_MULXSS, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"mulxsu", "d,s,t", "d,s,t,E", 3, OP_MATCH_MULXSU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"mulxuu", "d,s,t", "d,s,t,E", 3, OP_MATCH_MULXUU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"nextpc", "d", "d,E", 1, OP_MATCH_NEXTPC, OP_MASK_NEXTPC, 0, no_overflow },
+ {"nop", "", "E", 0, OP_MATCH_ADD, OP_MASK, NIOS2_INSN_MACRO_MOV, no_overflow },
+ {"nor", "d,s,t", "d,s,t,E", 3, OP_MATCH_NOR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"or", "d,s,t", "d,s,t,E", 3, OP_MATCH_OR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"orhi", "t,s,u", "t,s,u,E", 3, OP_MATCH_ORHI, OP_MASK_IOP, 0, unsigned_immed16_overflow },
+ {"ori", "t,s,u", "t,s,u,E", 3, OP_MATCH_ORI, OP_MASK_IOP, NIOS2_INSN_ORI, unsigned_immed16_overflow },
+ {"rdctl", "d,c", "d,c,E", 2, OP_MATCH_RDCTL, OP_MASK_RDCTL, 0, no_overflow },
+ {"ret", "", "E", 0, OP_MATCH_RET, OP_MASK, 0, no_overflow },
+ {"rol", "d,s,t", "d,s,t,E", 3, OP_MATCH_ROL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"roli", "d,s,j", "d,s,j,E", 3, OP_MATCH_ROLI, OP_MASK_ROLI, 0, unsigned_immed5_overflow },
+ {"ror", "d,s,t", "d,s,t,E", 3, OP_MATCH_ROR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"sll", "d,s,t", "d,s,t,E", 3, OP_MATCH_SLL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"slli", "d,s,j", "d,s,j,E", 3, OP_MATCH_SLLI, OP_MASK_SLLI, 0, unsigned_immed5_overflow },
+ {"sra", "d,s,t", "d,s,t,E", 3, OP_MATCH_SRA, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"srai", "d,s,j", "d,s,j,E", 3, OP_MATCH_SRAI, OP_MASK_SRAI, 0, unsigned_immed5_overflow },
+ {"srl", "d,s,t", "d,s,t,E", 3, OP_MATCH_SRL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"srli", "d,s,j", "d,s,j,E", 3, OP_MATCH_SRLI, OP_MASK_SRLI, 0, unsigned_immed5_overflow },
+ {"stb", "t,i(s)", "t,i(s)E", 3, OP_MATCH_STB, OP_MASK_IOP, 0, address_offset_overflow },
+ {"stbio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_STBIO, OP_MASK_IOP, 0, address_offset_overflow },
+ {"sth", "t,i(s)", "t,i(s)E", 3, OP_MATCH_STH, OP_MASK_IOP, 0, address_offset_overflow },
+ {"sthio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_STHIO, OP_MASK_IOP, 0, address_offset_overflow },
+ {"stw", "t,i(s)", "t,i(s)E", 3, OP_MATCH_STW, OP_MASK_IOP, 0, address_offset_overflow },
+ {"stwio", "t,i(s)", "t,i(s)E", 3, OP_MATCH_STWIO, OP_MASK_IOP, 0, address_offset_overflow },
+ {"sub", "d,s,t", "d,s,t,E", 3, OP_MATCH_SUB, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"sync", "", "E", 0, OP_MATCH_SYNC, OP_MASK_SYNC, 0, no_overflow },
+ {"trap", "", "E", 0, OP_MATCH_TRAP, OP_MASK_TRAP, 0, no_overflow },
+ {"eret", "", "E", 0, OP_MATCH_ERET, OP_MASK, 0, no_overflow },
+ {"custom", "l,d,s,t", "l,d,s,t,E", 4, OP_MATCH_CUSTOM, OP_MASK_ROP, 0, custom_opcode_overflow },
+ {"wrctl", "c,s", "c,s,E", 2, OP_MATCH_WRCTL, OP_MASK_WRCTL, 0, no_overflow },
+ {"xor", "d,s,t", "d,s,t,E", 3, OP_MATCH_XOR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow },
+ {"xorhi", "t,s,u", "t,s,u,E", 3, OP_MATCH_XORHI, OP_MASK_IOP, 0, unsigned_immed16_overflow },
+ {"xori", "t,s,u", "t,s,u,E", 3, OP_MATCH_XORI, OP_MASK_IOP, NIOS2_INSN_XORI, unsigned_immed16_overflow }
+};
+/* *INDENT-ON* */
+
+#define NIOS2_NUM_OPCODES \
+ ((sizeof nios2_builtin_opcodes) / (sizeof (nios2_builtin_opcodes[0])))
+const int bfd_nios2_num_builtin_opcodes = NIOS2_NUM_OPCODES;
+
+/* const removed from the following to allow for dynamic extensions to the
+ * built-in instruction set. */
+struct nios2_opcode *nios2_opcodes =
+ (struct nios2_opcode *) nios2_builtin_opcodes;
+int bfd_nios2_num_opcodes = NIOS2_NUM_OPCODES;
+#undef NIOS2_NUM_OPCODES