2013-05-06 Sandra Loosemore <sandra@codesourcery.com>
authorSandra Loosemore <sandra@codesourcery.com>
Tue, 7 May 2013 01:09:29 +0000 (01:09 +0000)
committerSandra Loosemore <sandra@codesourcery.com>
Tue, 7 May 2013 01:09:29 +0000 (01:09 +0000)
    Andrew Jenner  <andrew@codesourcery.com>
    Chung-Lin Tang  <cltang@codesourcery.com>
    Julian Brown  <julian@codesourcery.com>

Based on the nios2-elf port from Altera Corporation.

gdb/
* Makefile.in (ALL_TARGET_OBS): Add nios2-tdep.o and
nios2-linux-tdep.o.
(HFILES_NO_SRCDIR): Add nios2-tdep.h.
(ALLDEPFILES): Add nios2-tdep.c and nios2-linux-tdep.c.
* configure.tgt: Add nios2*-*-linux* and nios2*-*-* targets.
* nios2-tdep.h: New.
* nios2-tdep.c: New.
* nios2-linux-tdep.c: New.
* features/Makefile (WHICH): Add nios2-linux.
(nios2-linux-expedite): Set.
* features/nios2-cpu.xml: New.
* features/nios2.xml: New.
* features/nios2-linux.xml: New.
* features/nios2.c: New (autogenerated).
* features/nios2-linux.c: New (autogenerated).
* regformats/nios2-linux.dat: New (autogenerated).
* NEWS (Changes since GDB 7.6): Add new Nios II targets
and commands.

gdb/doc/
* gdb.texinfo (Nios II): New section.
(Nios II Features): New section.

16 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/NEWS
gdb/configure.tgt
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/features/Makefile
gdb/features/nios2-cpu.xml [new file with mode: 0644]
gdb/features/nios2-linux.c [new file with mode: 0644]
gdb/features/nios2-linux.xml [new file with mode: 0644]
gdb/features/nios2.c [new file with mode: 0644]
gdb/features/nios2.xml [new file with mode: 0644]
gdb/nios2-linux-tdep.c [new file with mode: 0644]
gdb/nios2-tdep.c [new file with mode: 0644]
gdb/nios2-tdep.h [new file with mode: 0644]
gdb/regformats/nios2-linux.dat [new file with mode: 0644]

index 9578da0d3890ca90cf1b97f05f454ea2af21098f..af14702e59d5bb7b118ca809965079af1560ce9a 100644 (file)
@@ -1,3 +1,29 @@
+2013-05-06  Sandra Loosemore  <sandra@codesourcery.com>
+           Andrew Jenner  <andrew@codesourcery.com>
+           Chung-Lin Tang  <cltang@codesourcery.com>
+           Julian Brown  <julian@codesourcery.com>
+
+       Based on the nios2-elf port from Altera Corporation.
+
+       * Makefile.in (ALL_TARGET_OBS): Add nios2-tdep.o and
+       nios2-linux-tdep.o.
+       (HFILES_NO_SRCDIR): Add nios2-tdep.h.
+       (ALLDEPFILES): Add nios2-tdep.c and nios2-linux-tdep.c.
+       * configure.tgt: Add nios2*-*-linux* and nios2*-*-* targets.
+       * nios2-tdep.h: New.
+       * nios2-tdep.c: New.
+       * nios2-linux-tdep.c: New.
+       * features/Makefile (WHICH): Add nios2-linux.
+       (nios2-linux-expedite): Set.
+       * features/nios2-cpu.xml: New.
+       * features/nios2.xml: New.
+       * features/nios2-linux.xml: New.
+       * features/nios2.c: New (autogenerated).
+       * features/nios2-linux.c: New (autogenerated).
+       * regformats/nios2-linux.dat: New (autogenerated).
+       * NEWS (Changes since GDB 7.6): Add new Nios II targets
+       and commands.
+
 2013-05-06  Doug Evans  <dje@google.com>
 
        * symfile.c: Whitespace cleanup.
index 625ca4a7280f0d5797e702fd37bacb03594f30d0..2597ddb87737cddc932f7684a7413ae3b7c5f626 100644 (file)
@@ -571,6 +571,7 @@ ALL_TARGET_OBS = \
        mn10300-linux-tdep.o mn10300-tdep.o \
        moxie-tdep.o \
        mt-tdep.o \
+       nios2-tdep.o nios2-linux-tdep.o \
        nto-tdep.o \
        ppc-linux-tdep.o ppcnbsd-tdep.o ppcobsd-tdep.o ppc-sysv-tdep.o \
        ppc64-tdep.o rl78-tdep.o \
@@ -834,7 +835,7 @@ psymtab.h psympriv.h progspace.h bfin-tdep.h ia64-hpux-tdep.h \
 amd64-darwin-tdep.h charset-list.h \
 config/djgpp/langinfo.h config/djgpp/nl_types.h darwin-nat.h \
 dicos-tdep.h filesystem.h gcore.h gdb_wchar.h hppabsd-tdep.h \
-i386-darwin-tdep.h i386-nat.h linux-record.h moxie-tdep.h \
+i386-darwin-tdep.h i386-nat.h linux-record.h moxie-tdep.h nios2-tdep.h \
 osdata.h procfs.h python/py-event.h python/py-events.h python/py-stopevent.h \
 python/python-internal.h python/python.h ravenscar-thread.h record.h \
 record-full.h solib-aix.h \
@@ -1516,6 +1517,7 @@ ALLDEPFILES = \
        mips-tdep.c \
        mipsnbsd-nat.c mipsnbsd-tdep.c \
        mips64obsd-nat.c mips64obsd-tdep.c \
+       nios2-tdep.c nios2-linux-tdep.c \
        nbsd-nat.c nbsd-tdep.c obsd-tdep.c \
        solib-osf.c \
        somread.c solib-som.c \
index 76b48e82e85d245ce68910a65392f805c626a0b0..65284dc32d4e344a334cdcb8f14878b6d3256067 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,11 @@
 
 *** Changes since GDB 7.6
 
+* New targets
+
+Nios II ELF                    nios2*-*-elf
+Nios II GNU/Linux              nios2*-*-linux
+
 * New commands:
 catch rethrow
   Like "catch throw", but catches a re-thrown exception.
@@ -22,6 +27,10 @@ set remote trace-status-packet
 show remote trace-status-packet
   Set/show the use of remote protocol qTStatus packet.
 
+set debug nios2
+show debug nios2
+  Control display of debugging messages related to Nios II targets.
+
 * You can now use a literal value 'unlimited' for options that
   interpret 0 or -1 as meaning "unlimited".  E.g., "set
   trace-buffer-size unlimited" is now an alias for "set
index 4acad87228112a0f26ee7d41abd10e43768df4ae..b0bee4757c28d5aba1fd857b7aded0763ae9f430 100644 (file)
@@ -396,6 +396,17 @@ mt-*-*)
        gdb_target_obs="mt-tdep.o"
        ;;
 
+nios2*-*-linux*)
+       # Target: Altera Nios II running Linux
+       gdb_target_obs="nios2-tdep.o nios2-linux-tdep.o solib-svr4.o \
+                       symfile-mem.o glibc-tdep.o linux-tdep.o"
+       ;;
+
+nios2*-*-*)
+       # Target: Altera Nios II bare-metal
+       gdb_target_obs="nios2-tdep.o"
+       ;;
+
 powerpc*-*-freebsd*)
        # Target: FreeBSD/powerpc
        gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \
index 8035f3eaa3c8224e5ee39c708421003c1a8784f9..324dd9d8d3f9ad5ed7c03a7c6d05f6abca6a041f 100644 (file)
@@ -1,3 +1,8 @@
+2013-05-06  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * gdb.texinfo (Nios II): New section.
+       (Nios II Features): New section.
+
 2013-05-06  Joel Brobecker  <brobecker@adacore.com>
 
        * gdbint.texinfo (Algorithms): Remove entries documenting
index 8bc12130b1adc85c1a8206a68a932fe40b77860c..39730c295e1a273414bee3381db27ce3eaa189d5 100644 (file)
@@ -20832,6 +20832,7 @@ all uses of @value{GDBN} with the architecture, both native and cross.
 * HPPA::               HP PA architecture
 * SPU::                Cell Broadband Engine SPU architecture
 * PowerPC::
+* Nios II::
 @end menu
 
 @node AArch64
@@ -21115,6 +21116,24 @@ by joining the even/odd register pairs @code{f0} and @code{f1} for @code{$dl0},
 For POWER7 processors, @value{GDBN} provides a set of pseudo-registers, the 64-bit
 wide Extended Floating Point Registers (@samp{f32} through @samp{f63}).
 
+@node Nios II
+@subsection Nios II
+@cindex Nios II architecture
+
+When @value{GDBN} is debugging the Nios II architecture,
+it provides the following special commands:
+
+@table @code
+
+@item set debug nios2
+@kindex set debug nios2
+This command turns on and off debugging messages for the Nios II
+target code in @value{GDBN}.
+
+@item show debug nios2
+@kindex show debug nios2
+Show the current setting of Nios II debugging messages.
+@end table
 
 @node Controlling GDB
 @chapter Controlling @value{GDBN}
@@ -41225,6 +41244,7 @@ registers using the capitalization used in the description.
 * i386 Features::
 * MIPS Features::
 * M68K Features::
+* Nios II Features::
 * PowerPC Features::
 * TIC6x Features::
 @end menu
@@ -41374,6 +41394,16 @@ This feature is optional.  If present, it should contain registers
 @samp{fpiaddr}.
 @end table
 
+@node Nios II Features
+@subsection Nios II Features
+@cindex target descriptions, Nios II features
+
+The @samp{org.gnu.gdb.nios2.cpu} feature is required for Nios II
+targets.  It should contain the 32 core registers (@samp{zero},
+@samp{at}, @samp{r2} through @samp{r23}, @samp{et} through @samp{ra}),
+@samp{pc}, and the 16 control registers (@samp{status} through
+@samp{mpuacc}).
+
 @node PowerPC Features
 @subsection PowerPC Features
 @cindex target descriptions, PowerPC features
index 4ba5cc3313deb5fe2b458c0c0840cac22bc8c486..e3a07e7130b18206191b9b2611584b9c9e65e409 100644 (file)
@@ -42,6 +42,7 @@ WHICH = aarch64 aarch64-without-fpu \
        i386/x32-avx i386/x32-avx-linux \
        mips-linux mips-dsp-linux \
        mips64-linux mips64-dsp-linux \
+       nios2-linux \
        rs6000/powerpc-32 \
        rs6000/powerpc-32l rs6000/powerpc-altivec32l rs6000/powerpc-e500l \
        rs6000/powerpc-64l rs6000/powerpc-altivec64l rs6000/powerpc-vsx32l \
@@ -73,6 +74,7 @@ mips-expedite = r29,pc
 mips-dsp-expedite = r29,pc
 mips64-expedite = r29,pc
 mips64-dsp-expedite = r29,pc
+nios2-linux-expedite = sp,pc
 powerpc-expedite = r1,pc
 rs6000/powerpc-cell32l-expedite = r1,pc,r0,orig_r3,r4
 rs6000/powerpc-cell64l-expedite = r1,pc,r0,orig_r3,r4
diff --git a/gdb/features/nios2-cpu.xml b/gdb/features/nios2-cpu.xml
new file mode 100644 (file)
index 0000000..a4146a6
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2012-2013 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.nios2.cpu">
+  <reg name="zero" bitsize="32" type="uint32"/>
+  <reg name="at" bitsize="32" type="uint32"/>
+  <reg name="r2" bitsize="32" type="uint32"/>
+  <reg name="r3" bitsize="32" type="uint32"/>
+  <reg name="r4" bitsize="32" type="uint32"/>
+  <reg name="r5" bitsize="32" type="uint32"/>
+  <reg name="r6" bitsize="32" type="uint32"/>
+  <reg name="r7" bitsize="32" type="uint32"/>
+  <reg name="r8" bitsize="32" type="uint32"/>
+  <reg name="r9" bitsize="32" type="uint32"/>
+  <reg name="r10" bitsize="32" type="uint32"/>
+  <reg name="r11" bitsize="32" type="uint32"/>
+  <reg name="r12" bitsize="32" type="uint32"/>
+  <reg name="r13" bitsize="32" type="uint32"/>
+  <reg name="r14" bitsize="32" type="uint32"/>
+  <reg name="r15" bitsize="32" type="uint32"/>
+  <reg name="r16" bitsize="32" type="uint32"/>
+  <reg name="r17" bitsize="32" type="uint32"/>
+  <reg name="r18" bitsize="32" type="uint32"/>
+  <reg name="r19" bitsize="32" type="uint32"/>
+  <reg name="r20" bitsize="32" type="uint32"/>
+  <reg name="r21" bitsize="32" type="uint32"/>
+  <reg name="r22" bitsize="32" type="uint32"/>
+  <reg name="r23" bitsize="32" type="uint32"/>
+  <reg name="et" bitsize="32" type="uint32"/>
+  <reg name="bt" bitsize="32" type="uint32"/>
+  <reg name="gp" bitsize="32" type="uint32"/>
+  <reg name="sp" bitsize="32" type="data_ptr"/>
+  <reg name="fp" bitsize="32" type="uint32"/>
+  <reg name="ea" bitsize="32" type="uint32"/>
+  <reg name="ba" bitsize="32" type="uint32"/>
+  <reg name="ra" bitsize="32" type="uint32"/>
+  <reg name="pc" bitsize="32" type="code_ptr"/>
+  <reg name="status" bitsize="32" type="uint32"/>
+  <reg name="estatus" bitsize="32" type="uint32"/>
+  <reg name="bstatus" bitsize="32" type="uint32"/>
+  <reg name="ienable" bitsize="32" type="uint32"/>
+  <reg name="ipending" bitsize="32" type="uint32"/>
+  <reg name="cpuid" bitsize="32" type="uint32"/>
+  <reg name="ctl6" bitsize="32" type="uint32"/>
+  <reg name="exception" bitsize="32" type="uint32"/>
+  <reg name="pteaddr" bitsize="32" type="uint32"/>
+  <reg name="tlbacc" bitsize="32" type="uint32"/>
+  <reg name="tlbmisc" bitsize="32" type="uint32"/>
+  <reg name="eccinj" bitsize="32" type="uint32"/>
+  <reg name="badaddr" bitsize="32" type="uint32"/>
+  <reg name="config" bitsize="32" type="uint32"/>
+  <reg name="mpubase" bitsize="32" type="uint32"/>
+  <reg name="mpuacc" bitsize="32" type="uint32"/>
+</feature>
diff --git a/gdb/features/nios2-linux.c b/gdb/features/nios2-linux.c
new file mode 100644 (file)
index 0000000..d384d7f
--- /dev/null
@@ -0,0 +1,71 @@
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: nios2-linux.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_nios2_linux;
+static void
+initialize_tdesc_nios2_linux (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  struct tdesc_feature *feature;
+
+  set_tdesc_architecture (result, bfd_scan_arch ("nios2"));
+
+  set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux"));
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.nios2.cpu");
+  tdesc_create_reg (feature, "zero", 0, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "at", 1, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r16", 16, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r17", 17, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r18", 18, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r19", 19, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r20", 20, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r21", 21, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r22", 22, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r23", 23, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "et", 24, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "bt", 25, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "gp", 26, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "sp", 27, 1, NULL, 32, "data_ptr");
+  tdesc_create_reg (feature, "fp", 28, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ea", 29, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ba", 30, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ra", 31, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "pc", 32, 1, NULL, 32, "code_ptr");
+  tdesc_create_reg (feature, "status", 33, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "estatus", 34, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "bstatus", 35, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ienable", 36, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ipending", 37, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cpuid", 38, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ctl6", 39, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "exception", 40, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "pteaddr", 41, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "tlbacc", 42, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "tlbmisc", 43, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "eccinj", 44, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "badaddr", 45, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "config", 46, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "mpubase", 47, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "mpuacc", 48, 1, NULL, 32, "uint32");
+
+  tdesc_nios2_linux = result;
+}
diff --git a/gdb/features/nios2-linux.xml b/gdb/features/nios2-linux.xml
new file mode 100644 (file)
index 0000000..f262df2
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2012-2013 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>nios2</architecture>
+  <osabi>GNU/Linux</osabi>
+  <xi:include href="nios2-cpu.xml"/>
+</target>
diff --git a/gdb/features/nios2.c b/gdb/features/nios2.c
new file mode 100644 (file)
index 0000000..cb7246d
--- /dev/null
@@ -0,0 +1,69 @@
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: nios2.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_nios2;
+static void
+initialize_tdesc_nios2 (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  struct tdesc_feature *feature;
+
+  set_tdesc_architecture (result, bfd_scan_arch ("nios2"));
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.nios2.cpu");
+  tdesc_create_reg (feature, "zero", 0, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "at", 1, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r16", 16, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r17", 17, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r18", 18, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r19", 19, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r20", 20, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r21", 21, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r22", 22, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r23", 23, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "et", 24, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "bt", 25, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "gp", 26, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "sp", 27, 1, NULL, 32, "data_ptr");
+  tdesc_create_reg (feature, "fp", 28, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ea", 29, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ba", 30, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ra", 31, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "pc", 32, 1, NULL, 32, "code_ptr");
+  tdesc_create_reg (feature, "status", 33, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "estatus", 34, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "bstatus", 35, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ienable", 36, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ipending", 37, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cpuid", 38, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ctl6", 39, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "exception", 40, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "pteaddr", 41, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "tlbacc", 42, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "tlbmisc", 43, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "eccinj", 44, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "badaddr", 45, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "config", 46, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "mpubase", 47, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "mpuacc", 48, 1, NULL, 32, "uint32");
+
+  tdesc_nios2 = result;
+}
diff --git a/gdb/features/nios2.xml b/gdb/features/nios2.xml
new file mode 100644 (file)
index 0000000..25849bb
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>nios2</architecture>
+  <xi:include href="nios2-cpu.xml"/>
+</target>
diff --git a/gdb/nios2-linux-tdep.c b/gdb/nios2-linux-tdep.c
new file mode 100644 (file)
index 0000000..67f4007
--- /dev/null
@@ -0,0 +1,233 @@
+/* Target-dependent code for GNU/Linux on Nios II.
+   Copyright (C) 2012-2013 Free Software Foundation, Inc.
+   Contributed by Mentor Graphics, Inc.
+
+   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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "frame.h"
+#include "gdb_assert.h"
+#include "gdb_string.h"
+#include "osabi.h"
+#include "solib-svr4.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
+#include "symtab.h"
+#include "regset.h"
+#include "regcache.h"
+#include "linux-tdep.h"
+#include "glibc-tdep.h"
+#include "nios2-tdep.h"
+
+#include "features/nios2-linux.c"
+
+/* Core file and register set support.  */
+
+/* Map from the normal register enumeration order to the order that
+   registers appear in core files, which corresponds to the order
+   of the register slots in the kernel's struct pt_regs.  */
+
+static const int reg_offsets[NIOS2_NUM_REGS] =
+{
+  -1,  8,  9, 10, 11, 12, 13, 14,      /* r0 - r7 */
+  0,  1,  2,  3,  4,  5,  6,  7,       /* r8 - r15 */
+  23, 24, 25, 26, 27, 28, 29, 30,      /* r16 - r23 */
+  -1, -1, 19, 18, 17, 21, -1, 16,      /* et bt gp sp fp ea ba ra */
+  21,                                  /* pc */
+  -1, 20, -1, -1, -1, -1, -1, -1,      /* status estatus ...  */
+  -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+/* Implement the supply_regset hook for core files.  */
+
+static void
+nios2_supply_gregset (const struct regset *regset,
+                     struct regcache *regcache,
+                     int regnum, const void *gregs_buf, size_t len)
+{
+  const gdb_byte *gregs = gregs_buf;
+  int regno;
+  static const gdb_byte zero_buf[4] = {0, 0, 0, 0};
+
+  for (regno = NIOS2_Z_REGNUM; regno <= NIOS2_MPUACC_REGNUM; regno++)
+    if (regnum == -1 || regnum == regno)
+      {
+       if (reg_offsets[regno] != -1)
+         regcache_raw_supply (regcache, regno,
+                              gregs + 4 * reg_offsets[regno]);
+       else
+         regcache_raw_supply (regcache, regno, zero_buf);
+      }
+}
+
+static struct regset nios2_core_regset =
+{
+  NULL,
+  nios2_supply_gregset,
+  NULL,
+  NULL
+};
+
+/* Implement the regset_from_core_section gdbarch method.  */
+
+static const struct regset *
+nios2_regset_from_core_section (struct gdbarch *gdbarch,
+                                const char *sect_name, size_t sect_size)
+{
+  if (strcmp (sect_name, ".reg") == 0)
+    return &nios2_core_regset;
+
+  return NULL;
+}
+
+/* Initialize a trad-frame cache corresponding to the tramp-frame.
+   FUNC is the address of the instruction TRAMP[0] in memory.  */
+
+static void
+nios2_linux_sigreturn_init (const struct tramp_frame *self,
+                           struct frame_info *next_frame,
+                           struct trad_frame_cache *this_cache,
+                           CORE_ADDR func)
+{
+  CORE_ADDR base = func + 16;
+  int i;
+
+  for (i = 0; i < 8; i++)
+    trad_frame_set_reg_addr (this_cache, i + 8, base + i * 4);
+  for (i = 0; i < 7; i++)
+    trad_frame_set_reg_addr (this_cache, i + 1, base + (i + 8) * 4);
+  trad_frame_set_reg_addr (this_cache, NIOS2_RA_REGNUM, base + 16 * 4);
+  trad_frame_set_reg_addr (this_cache, NIOS2_FP_REGNUM, base + 17 * 4);
+  trad_frame_set_reg_addr (this_cache, NIOS2_SP_REGNUM, base + 18 * 4);
+  trad_frame_set_reg_addr (this_cache, NIOS2_GP_REGNUM, base + 19 * 4);
+  trad_frame_set_reg_addr (this_cache, NIOS2_ESTATUS_REGNUM, base + 20 * 4);
+  trad_frame_set_reg_addr (this_cache, NIOS2_PC_REGNUM, base + 21 * 4);
+
+  /* Save a frame ID.  */
+  trad_frame_set_id (this_cache, frame_id_build (base, func));
+}
+
+/* Initialize a trad-frame cache corresponding to the tramp-frame.
+   FUNC is the address of the instruction TRAMP[0] in memory.  */
+
+static void
+nios2_linux_rt_sigreturn_init (const struct tramp_frame *self,
+                              struct frame_info *next_frame,
+                              struct trad_frame_cache *this_cache,
+                              CORE_ADDR func)
+{
+  CORE_ADDR base = func + 41 * 4;
+  int i;
+
+  for (i = 0; i < 23; i++)
+    trad_frame_set_reg_addr (this_cache, i + 1, base + i * 4);
+  trad_frame_set_reg_addr (this_cache, NIOS2_RA_REGNUM, base + 23 * 4);
+  trad_frame_set_reg_addr (this_cache, NIOS2_FP_REGNUM, base + 24 * 4);
+  trad_frame_set_reg_addr (this_cache, NIOS2_GP_REGNUM, base + 25 * 4);
+  trad_frame_set_reg_addr (this_cache, NIOS2_PC_REGNUM, base + 27 * 4);
+  trad_frame_set_reg_addr (this_cache, NIOS2_SP_REGNUM, base + 28 * 4);
+
+  /* Save a frame ID.  */
+  trad_frame_set_id (this_cache, frame_id_build (base, func));
+}
+
+static struct tramp_frame nios2_linux_sigreturn_tramp_frame =
+{
+  SIGTRAMP_FRAME,
+  4,
+  {
+    { 0x00800004 | (119 << 6), -1 },  /* movi r2,__NR_sigreturn */
+    { 0x003b683a, -1 },               /* trap */
+    { TRAMP_SENTINEL_INSN }
+  },
+  nios2_linux_sigreturn_init
+};
+
+static struct tramp_frame nios2_linux_rt_sigreturn_tramp_frame =
+{
+  SIGTRAMP_FRAME,
+  4,
+  {
+    { 0x00800004 | (173 << 6), -1 },  /* movi r2,__NR_rt_sigreturn */
+    { 0x003b683a, -1 },               /* trap */
+    { TRAMP_SENTINEL_INSN }
+  },
+  nios2_linux_rt_sigreturn_init
+};
+
+/* When FRAME is at a syscall instruction, return the PC of the next
+   instruction to be executed.  */
+
+static CORE_ADDR
+nios2_linux_syscall_next_pc (struct frame_info *frame)
+{
+  CORE_ADDR pc = get_frame_pc (frame);
+  ULONGEST syscall_nr = get_frame_register_unsigned (frame, NIOS2_R2_REGNUM);
+
+  /* If we are about to make a sigreturn syscall, use the unwinder to
+     decode the signal frame.  */
+  if (syscall_nr == 119 /* sigreturn */
+      || syscall_nr == 173 /* rt_sigreturn */)
+    return frame_unwind_caller_pc (frame);
+
+  return pc + NIOS2_OPCODE_SIZE;
+}
+
+/* Hook function for gdbarch_register_osabi.  */
+
+static void
+nios2_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  linux_init_abi (info, gdbarch);
+
+  /* Shared library handling.  */
+  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+  set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
+
+  set_solib_svr4_fetch_link_map_offsets (gdbarch,
+                                        svr4_ilp32_fetch_link_map_offsets);
+  /* Enable TLS support.  */
+  set_gdbarch_fetch_tls_load_module_address (gdbarch,
+                                             svr4_fetch_objfile_link_map);
+  /* Core file support.  */
+  set_gdbarch_regset_from_core_section (gdbarch,
+                                        nios2_regset_from_core_section);
+  /* Linux signal frame unwinders.  */
+  tramp_frame_prepend_unwinder (gdbarch,
+                                &nios2_linux_sigreturn_tramp_frame);
+  tramp_frame_prepend_unwinder (gdbarch,
+                                &nios2_linux_rt_sigreturn_tramp_frame);
+
+  tdep->syscall_next_pc = nios2_linux_syscall_next_pc;
+
+  /* Index of target address word in glibc jmp_buf.  */
+  tdep->jb_pc = 10;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+
+extern initialize_file_ftype _initialize_nios2_linux_tdep;
+
+void
+_initialize_nios2_linux_tdep (void)
+{
+  gdbarch_register_osabi (bfd_arch_nios2, 0, GDB_OSABI_LINUX,
+                          nios2_linux_init_abi);
+
+  initialize_tdesc_nios2_linux ();
+}
diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c
new file mode 100644 (file)
index 0000000..055dc76
--- /dev/null
@@ -0,0 +1,1637 @@
+/* Target-machine dependent code for Nios II, for GDB.
+   Copyright (C) 2012-2013 Free Software Foundation, Inc.
+   Contributed by Peter Brookes (pbrookes@altera.com)
+   and Andrew Draper (adraper@altera.com).
+   Contributed by Mentor Graphics, Inc.
+
+   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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#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 "osabi.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"
+#include "infcall.h"
+#include "regset.h"
+#include "target-descriptions.h"
+
+/* To get entry_point_address.  */
+#include "objfiles.h"
+
+/* Nios II ISA specific encodings and macros.  */
+#include "opcode/nios2.h"
+
+/* Nios II specific header.  */
+#include "nios2-tdep.h"
+
+#include "features/nios2.c"
+
+/* Control debugging information emitted in this file.  */
+
+static int nios2_debug = 0;
+
+/* The following structures are used in the cache for prologue
+   analysis; see the reg_value and reg_saved tables in
+   struct nios2_unwind_cache, respectively.  */
+
+/* struct reg_value is used to record that a register has the same value
+   as reg at the given offset from the start of a function.  */
+
+struct reg_value
+{
+  int reg;
+  unsigned int offset;
+};
+
+/* struct reg_saved is used to record that a register value has been saved at
+   basereg + addr, for basereg >= 0.  If basereg < 0, that indicates
+   that the register is not known to have been saved.  Note that when
+   basereg == NIOS2_Z_REGNUM (that is, r0, which holds value 0),
+   addr is an absolute address.  */
+
+struct reg_saved
+{
+  int basereg;
+  CORE_ADDR addr;
+};
+
+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.  */
+  struct reg_value reg_value[NIOS2_NUM_REGS];
+
+  /* Table indicating where each register has been saved.  */
+  struct reg_saved reg_saved[NIOS2_NUM_REGS];
+};
+
+
+/* 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,
+  NIOS2_GP_REGNUM,        /* 26 */
+  NIOS2_SP_REGNUM,        /* 27 */
+  NIOS2_FP_REGNUM,        /* 28 */
+  NIOS2_EA_REGNUM,        /* 29 */
+  NIOS2_BA_REGNUM,        /* 30 */
+  NIOS2_RA_REGNUM,        /* 31 */
+  NIOS2_PC_REGNUM,        /* 32 */
+  NIOS2_STATUS_REGNUM,    /* 33 */
+  NIOS2_ESTATUS_REGNUM,   /* 34 */
+  NIOS2_BSTATUS_REGNUM,   /* 35 */
+  NIOS2_IENABLE_REGNUM,   /* 36 */
+  NIOS2_IPENDING_REGNUM,  /* 37 */
+  NIOS2_CPUID_REGNUM,     /* 38 */
+  39, /* CTL6 */          /* 39 */
+  NIOS2_EXCEPTION_REGNUM, /* 40 */
+  NIOS2_PTEADDR_REGNUM,   /* 41 */
+  NIOS2_TLBACC_REGNUM,    /* 42 */
+  NIOS2_TLBMISC_REGNUM,   /* 43 */
+  NIOS2_ECCINJ_REGNUM,    /* 44 */
+  NIOS2_BADADDR_REGNUM,   /* 45 */
+  NIOS2_CONFIG_REGNUM,    /* 46 */
+  NIOS2_MPUBASE_REGNUM,   /* 47 */
+  NIOS2_MPUACC_REGNUM     /* 48 */
+};
+
+
+/* Implement the dwarf2_reg_to_regnum gdbarch method.  */
+
+static int
+nios2_dwarf_reg_to_regnum (struct gdbarch *gdbarch, 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];
+}
+
+/* Canonical names for the 49 registers.  */
+
+static const char *const nios2_reg_names[NIOS2_NUM_REGS] =
+{
+  "zero", "at", "r2", "r3", "r4", "r5", "r6", "r7",
+  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+  "et", "bt", "gp", "sp", "fp", "ea", "ba", "ra",
+  "pc",
+  "status", "estatus", "bstatus", "ienable",
+  "ipending", "cpuid", "ctl6", "exception",
+  "pteaddr", "tlbacc", "tlbmisc", "eccinj",
+  "badaddr", "config", "mpubase", "mpuacc"
+};
+
+/* Implement the register_name gdbarch method.  */
+
+static const char *
+nios2_register_name (struct gdbarch *gdbarch, int regno)
+{
+  /* Use mnemonic aliases for GPRs.  */
+  if (regno >= 0 && regno < NIOS2_NUM_REGS)
+    return nios2_reg_names[regno];
+  else
+    return tdesc_register_name (gdbarch, regno);
+}
+
+/* Implement the register_type gdbarch method.  */
+
+static struct type *
+nios2_register_type (struct gdbarch *gdbarch, int regno)
+{
+  /* If the XML description has register information, use that to
+     determine the register type.  */
+  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    return tdesc_register_type (gdbarch, regno);
+
+  if (regno == NIOS2_PC_REGNUM)
+    return builtin_type (gdbarch)->builtin_func_ptr;
+  else if (regno == NIOS2_SP_REGNUM)
+    return builtin_type (gdbarch)->builtin_data_ptr;
+  else
+    return builtin_type (gdbarch)->builtin_uint32;
+}
+
+/* Given a return value in REGCACHE with a type VALTYPE,
+   extract and copy its value into VALBUF.  */
+
+static void
+nios2_extract_return_value (struct gdbarch *gdbarch, struct type *valtype,
+                           struct regcache *regcache, gdb_byte *valbuf)
+{
+  int len = TYPE_LENGTH (valtype);
+
+  /* Return values of up to 8 bytes are returned in $r2 $r3.  */
+  if (len <= register_size (gdbarch, NIOS2_R2_REGNUM))
+    regcache_cooked_read (regcache, NIOS2_R2_REGNUM, valbuf);
+  else
+    {
+      gdb_assert (len <= (register_size (gdbarch, NIOS2_R2_REGNUM)
+                         + register_size (gdbarch, NIOS2_R3_REGNUM)));
+      regcache_cooked_read (regcache, NIOS2_R2_REGNUM, valbuf);
+      regcache_cooked_read (regcache, NIOS2_R3_REGNUM, valbuf + 4);
+    }
+}
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+static void
+nios2_store_return_value (struct gdbarch *gdbarch, struct type *valtype,
+                         struct regcache *regcache, const gdb_byte *valbuf)
+{
+  int len = TYPE_LENGTH (valtype);
+
+  /* Return values of up to 8 bytes are returned in $r2 $r3.  */
+  if (len <= register_size (gdbarch, NIOS2_R2_REGNUM))
+    regcache_cooked_write (regcache, NIOS2_R2_REGNUM, valbuf);
+  else
+    {
+      gdb_assert (len <= (register_size (gdbarch, NIOS2_R2_REGNUM)
+                         + register_size (gdbarch, NIOS2_R3_REGNUM)));
+      regcache_cooked_write (regcache, NIOS2_R2_REGNUM, valbuf);
+      regcache_cooked_write (regcache, NIOS2_R3_REGNUM, valbuf + 4);
+    }
+}
+
+
+/* Set up the default values of the registers.  */
+
+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;
+  }
+}
+
+/* Initialize the unwind cache.  */
+
+static void
+nios2_init_cache (struct nios2_unwind_cache *cache, CORE_ADDR pc)
+{
+  cache->base = 0;
+  cache->cfa = 0;
+  cache->pc = pc;
+  cache->return_regnum = NIOS2_RA_REGNUM;
+  nios2_setup_default (cache);
+}
+
+/* Helper function to identify when we're in a function epilogue;
+   that is, the part of the function from the point at which the
+   stack adjustment is made, to the return or sibcall.  On Nios II,
+   we want to check that the CURRENT_PC is a return-type instruction
+   and that the previous instruction is a stack adjustment.
+   START_PC is the beginning of the function in question.  */
+
+static int
+nios2_in_epilogue_p (struct gdbarch *gdbarch,
+                    CORE_ADDR current_pc,
+                    CORE_ADDR start_pc)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+  /* There has to be a previous instruction in the function.  */
+  if (current_pc > start_pc)
+    {
+
+      /* Check whether the previous instruction was a stack
+        adjustment.  */
+      unsigned int insn
+        = read_memory_unsigned_integer (current_pc - NIOS2_OPCODE_SIZE,
+                                       NIOS2_OPCODE_SIZE, byte_order);
+
+      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,
+                                              byte_order);
+
+         if (insn == 0xf800283a                        /* RET */
+             || insn == 0xe800083a                     /* ERET */
+             || (insn & 0x07ffffff) == 0x0000683a      /* JMP */
+             || (insn & 0xffc0003f) == 6)              /* BR */
+           return 1;
+       }
+    }
+  return 0;
+}
+
+/* Implement the in_function_epilogue_p gdbarch method.  */
+
+static int
+nios2_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  CORE_ADDR func_addr;
+
+  if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
+    return nios2_in_epilogue_p (gdbarch, pc, func_addr);
+
+  return 0;
+}
+
+/* Define some instruction patterns supporting wildcard bits via a
+   mask.  */
+
+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> */
+};
+
+
+/* Attempt to match SEQUENCE, which is COUNT insns long, at START_PC.  */
+
+static int
+nios2_match_sequence (struct gdbarch *gdbarch, CORE_ADDR start_pc,
+                     const wild_insn *sequence, int count)
+{
+  CORE_ADDR pc = start_pc;
+  int i;
+  unsigned int insn;
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+  for (i = 0 ; i < count ; i++)
+    {
+      insn = read_memory_unsigned_integer (pc, NIOS2_OPCODE_SIZE, byte_order);
+      if ((insn & ~sequence[i].mask) != sequence[i].insn)
+       return 0;
+
+      pc += NIOS2_OPCODE_SIZE;
+    }
+
+  return 1;
+}
+
+/* Do prologue analysis, returning the PC of the first instruction
+   after the function prologue.  Assumes CACHE has already been
+   initialized.  THIS_FRAME can be null, in which case we are only
+   interested in skipping the prologue.  Otherwise CACHE is filled in
+   from the frame information.
+
+   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.  */
+
+static CORE_ADDR
+nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
+                       const CORE_ADDR current_pc,
+                       struct nios2_unwind_cache *cache,
+                       struct frame_info *this_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;
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+  /* Does the frame set up the FP register?  */
+  int base_reg = 0;
+
+  struct reg_value *value = cache->reg_value;
+  struct 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 = (this_frame ? (frame_relative_level (this_frame) == 0) : 1);
+
+  if (nios2_debug)
+    fprintf_unfiltered (gdb_stdlog,
+                       "{ nios2_analyze_prologue start=%s, current=%s ",
+                       paddress (gdbarch, start_pc),
+                       paddress (gdbarch, current_pc));
+
+  /* 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 (gdbarch, pc, profiler_insn,
+                           ARRAY_SIZE (profiler_insn)))
+    pc += ARRAY_SIZE (profiler_insn) * NIOS2_OPCODE_SIZE;
+
+  /* If the first few instructions are an interrupt entry, then skip
+     over them too.  */
+  if (nios2_match_sequence (gdbarch, pc, irqentry_insn,
+                           ARRAY_SIZE (irqentry_insn)))
+    {
+      pc += ARRAY_SIZE (irqentry_insn) * NIOS2_OPCODE_SIZE;
+      exception_handler = 1;
+    }
+
+  prologue_end = start_pc;
+
+  /* Find the prologue instructions.  */
+  while (pc < limit_pc && within_prologue)
+    {
+      /* Present instruction.  */
+      uint32_t 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;
+       if (nios2_debug)
+         fprintf_unfiltered (gdb_stdlog, "*");
+      }
+
+      insn = read_memory_unsigned_integer (pc, NIOS2_OPCODE_SIZE, byte_order);
+      pc += NIOS2_OPCODE_SIZE;
+
+      if (nios2_debug)
+       fprintf_unfiltered (gdb_stdlog, "[%08X]", insn);
+
+      /* 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 == NIOS2_SP_REGNUM
+             && rb == 0
+             && value[ra].reg == cache->reg_saved[NIOS2_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 == NIOS2_SP_REGNUM)
+                   cache->reg_saved[i].basereg = -1;
+                 if (value[i].reg == NIOS2_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[NIOS2_SP_REGNUM].reg = NIOS2_SP_REGNUM;
+             value[NIOS2_SP_REGNUM].offset
+               = (value[ra].offset
+                  - cache->reg_saved[NIOS2_SP_REGNUM].addr
+                  - 4);
+             cache->reg_saved[NIOS2_SP_REGNUM].basereg = NIOS2_SP_REGNUM;
+             cache->reg_saved[NIOS2_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);
+
+         /* 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 (rb == NIOS2_SP_REGNUM
+             && (value[rb].offset != 0 || value[ra].reg != NIOS2_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 == NIOS2_EA_REGNUM && value[rb].offset == -4)))
+           {
+             /* We are most interested in stores to the stack, but
+                also take note of stores to other places as they
+                might be useful later.  */
+             if ((value[ra].reg == NIOS2_SP_REGNUM
+                  && cache->reg_saved[orig].basereg != NIOS2_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 == NIOS2_EA_REGNUM || orig == NIOS2_ESTATUS_REGNUM)
+                   exception_handler = 1;
+               }
+           }
+         else
+           /* Non-stack memory writes are not part of the
+              prologue.  */
+           within_prologue = 0;
+        }
+
+      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    = NIOS2_STATUS_REGNUM + n;
+             value[rc].offset = 0;
+           }
+
+         prologue_insn = 1;
+        }
+
+      else if ((insn & 0x0000003f) == 0
+              && value[8].reg == NIOS2_RA_REGNUM
+              && value[8].offset == 0
+              && value[NIOS2_SP_REGNUM].reg == NIOS2_SP_REGNUM
+              && value[NIOS2_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.
+            Note 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[NIOS2_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, byte_order);
+
+         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,
+                                           byte_order);
+
+         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;
+             break;
+           default:
+             break;
+           }
+       }
+
+      if (prologue_insn)
+       prologue_end = pc;
+    }
+
+  /* If THIS_FRAME is NULL, we are being called from skip_prologue
+     and are only interested in the PROLOGUE_END value, so just
+     return that now and skip over the cache updates, which depend
+     on having frame information.  */
+  if (this_frame == NULL)
+    return prologue_end;
+
+  /* If we are in the function epilogue and have already popped
+     registers off the stack in preparation for returning, then we
+     want to go back to the original register values.  */
+  if (innermost && nios2_in_epilogue_p (gdbarch, current_pc, start_pc))
+    nios2_setup_default (cache);
+
+  /* Exception handlers use a different return address register.  */
+  if (exception_handler)
+    cache->return_regnum = NIOS2_EA_REGNUM;
+
+  if (nios2_debug)
+    fprintf_unfiltered (gdb_stdlog, "\n-> retreg=%d, ", cache->return_regnum);
+
+  if (cache->reg_value[NIOS2_FP_REGNUM].reg == NIOS2_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 = NIOS2_FP_REGNUM;
+  else if (cache->reg_value[NIOS2_SP_REGNUM].reg == NIOS2_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 = NIOS2_SP_REGNUM;
+  else
+    {
+      /* Somehow the stack pointer has been corrupted.
+        We can't return.  */
+      if (nios2_debug)
+       fprintf_unfiltered (gdb_stdlog, "<can't reach cfa> }\n");
+      return 0;
+    }
+
+  if (cache->reg_value[base_reg].offset == 0
+      || cache->reg_saved[NIOS2_RA_REGNUM].basereg != NIOS2_SP_REGNUM
+      || cache->reg_saved[cache->return_regnum].basereg != NIOS2_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
+            wasn't interrupted.  */
+         CORE_ADDR ra
+           = get_frame_register_unsigned (this_frame, NIOS2_RA_REGNUM);
+
+         if (ra == current_pc)
+           {
+             if (nios2_debug)
+               fprintf_unfiltered
+                 (gdb_stdlog,
+                  "<noreturn ADJUST %s, r31@r%d+?>, r%d@r%d+?> }\n",
+                  paddress (gdbarch, cache->reg_value[base_reg].offset),
+                  cache->reg_saved[NIOS2_RA_REGNUM].basereg,
+                  cache->return_regnum,
+                  cache->reg_saved[cache->return_regnum].basereg);
+             return 0;
+           }
+       }
+    }
+
+  /* Get the value of whichever register we are using for the
+     base.  */
+  cache->base = get_frame_register_unsigned (this_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 == NIOS2_SP_REGNUM)
+      {
+       cache->reg_saved[i].basereg = NIOS2_Z_REGNUM;
+       cache->reg_saved[i].addr += frame_high;
+      }
+
+  for (i = 0; i < NIOS2_NUM_REGS; i++)
+    if (cache->reg_saved[i].basereg == NIOS2_GP_REGNUM)
+      {
+       CORE_ADDR gp = get_frame_register_unsigned (this_frame,
+                                                   NIOS2_GP_REGNUM);
+
+       for ( ; i < NIOS2_NUM_REGS; i++)
+         if (cache->reg_saved[i].basereg == NIOS2_GP_REGNUM)
+           {
+             cache->reg_saved[i].basereg = NIOS2_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[NIOS2_SP_REGNUM].basereg == NIOS2_Z_REGNUM)
+    cache->cfa
+      = read_memory_unsigned_integer (cache->reg_saved[NIOS2_SP_REGNUM].addr,
+                                     4, byte_order);
+  else
+    cache->cfa = frame_high;
+
+  /* Exception handlers restore ESTATUS into STATUS.  */
+  if (exception_handler)
+    {
+      cache->reg_saved[NIOS2_STATUS_REGNUM]
+       = cache->reg_saved[NIOS2_ESTATUS_REGNUM];
+      cache->reg_saved[NIOS2_ESTATUS_REGNUM].basereg = -1;
+    }
+
+  if (nios2_debug)
+    fprintf_unfiltered (gdb_stdlog, "cfa=%s }\n",
+                       paddress (gdbarch, cache->cfa));
+
+  return prologue_end;
+}
+
+/* Implement the skip_prologue gdbarch hook.  */
+
+static CORE_ADDR
+nios2_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
+{
+  CORE_ADDR limit_pc;
+  CORE_ADDR func_addr;
+
+  struct nios2_unwind_cache cache;
+
+  /* See if we can determine the end of the prologue via the symbol
+     table.  If so, then return either PC, or the PC after the
+     prologue, whichever is greater.  */
+  if (find_pc_partial_function (start_pc, NULL, &func_addr, NULL))
+    {
+      CORE_ADDR post_prologue_pc
+        = skip_prologue_using_sal (gdbarch, func_addr);
+
+      if (post_prologue_pc != 0)
+        return max (start_pc, post_prologue_pc);
+    }
+
+  /* Prologue analysis does the rest....  */
+  nios2_init_cache (&cache, start_pc);
+  return nios2_analyze_prologue (gdbarch, start_pc, start_pc, &cache, NULL);
+}
+
+/* Implement the breakpoint_from_pc gdbarch hook.  */
+
+static const gdb_byte*
+nios2_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
+                         int *bp_size)
+{
+  /* break encoding: 31->27  26->22  21->17  16->11 10->6 5->0 */
+  /*                 00000   00000   0x1d    0x2d   11111 0x3a */
+  /*                 00000   00000   11101   101101 11111 111010 */
+  /* In bytes:       00000000 00111011 01101111 11111010 */
+  /*                 0x0       0x3b    0x6f     0xfa */
+  static const gdb_byte breakpoint_le[] = {0xfa, 0x6f, 0x3b, 0x0};
+  static const gdb_byte breakpoint_be[] = {0x0, 0x3b, 0x6f, 0xfa};
+
+  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
+
+  *bp_size = 4;
+  if (gdbarch_byte_order_for_code (gdbarch) == BFD_ENDIAN_BIG)
+    return breakpoint_be;
+  else
+    return breakpoint_le;
+}
+
+/* Implement the print_insn gdbarch method.  */
+
+static int
+nios2_print_insn (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);
+}
+
+
+/* Implement the frame_align gdbarch method.  */
+
+static CORE_ADDR
+nios2_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+  return align_down (addr, 4);
+}
+
+
+/* Implement the return_value gdbarch method.  */
+
+static enum return_value_convention
+nios2_return_value (struct gdbarch *gdbarch, struct value *function,
+                   struct type *type, struct regcache *regcache,
+                   gdb_byte *readbuf, const gdb_byte *writebuf)
+{
+  if (TYPE_LENGTH (type) > 8)
+    return RETURN_VALUE_STRUCT_CONVENTION;
+
+  if (readbuf)
+    nios2_extract_return_value (gdbarch, type, regcache, readbuf);
+  if (writebuf)
+    nios2_store_return_value (gdbarch, type, regcache, writebuf);
+
+  return RETURN_VALUE_REGISTER_CONVENTION;
+}
+
+/* Implement the dummy_id gdbarch method.  */
+
+static struct frame_id
+nios2_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+{
+  return frame_id_build
+    (get_frame_register_unsigned (this_frame, NIOS2_SP_REGNUM),
+     get_frame_pc (this_frame));
+}
+
+/* Implement the push_dummy_call gdbarch method.  */
+
+static CORE_ADDR
+nios2_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
+                       struct regcache *regcache, CORE_ADDR bp_addr,
+                       int nargs, struct value **args, CORE_ADDR sp,
+                       int struct_return, CORE_ADDR struct_addr)
+{
+  int argreg;
+  int float_argreg;
+  int argnum;
+  int len = 0;
+  int stack_offset = 0;
+  CORE_ADDR func_addr = find_function_addr (function, NULL);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+  /* Set the return address register to point to the entry point of
+     the program, where a breakpoint lies in wait.  */
+  regcache_cooked_write_signed (regcache, NIOS2_RA_REGNUM, bp_addr);
+
+  /* Now make space on the stack for the args.  */
+  for (argnum = 0; argnum < nargs; argnum++)
+    len += align_up (TYPE_LENGTH (value_type (args[argnum])), 4);
+  sp -= len;
+
+  /* Initialize the register pointer.  */
+  argreg = NIOS2_FIRST_ARGREG;
+
+  /* The struct_return pointer occupies the first parameter-passing
+     register.  */
+  if (struct_return)
+    regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
+
+  /* Now load as many as possible of the first arguments into
+     registers, and push the rest onto the stack.  Loop through args
+     from first to last.  */
+  for (argnum = 0; argnum < nargs; argnum++)
+    {
+      const gdb_byte *val;
+      gdb_byte valbuf[MAX_REGISTER_SIZE];
+      struct value *arg = args[argnum];
+      struct type *arg_type = check_typedef (value_type (arg));
+      int len = TYPE_LENGTH (arg_type);
+      enum type_code typecode = TYPE_CODE (arg_type);
+
+      val = value_contents (arg);
+
+      /* Copy the argument to general registers or the stack in
+         register-sized pieces.  Large arguments are split between
+         registers and stack.  */
+      while (len > 0)
+        {
+         int partial_len = (len < 4 ? len : 4);
+
+         if (argreg <= NIOS2_LAST_ARGREG)
+           {
+             /* The argument is being passed in a register.  */
+             CORE_ADDR regval = extract_unsigned_integer (val, partial_len,
+                                                          byte_order);
+
+             regcache_cooked_write_unsigned (regcache, argreg, regval);
+             argreg++;
+           }
+         else
+           {
+             /* The argument is being passed on the stack.  */
+             CORE_ADDR addr = sp + stack_offset;
+
+             write_memory (addr, val, partial_len);
+             stack_offset += align_up (partial_len, 4);
+           }
+
+         len -= partial_len;
+         val += partial_len;
+       }
+    }
+
+  regcache_cooked_write_signed (regcache, NIOS2_SP_REGNUM, sp);
+
+  /* Return adjusted stack pointer.  */
+  return sp;
+}
+
+/* Implement the unwind_pc gdbarch method.  */
+
+static CORE_ADDR
+nios2_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+  gdb_byte buf[4];
+
+  frame_unwind_register (next_frame, NIOS2_PC_REGNUM, buf);
+  return extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);
+}
+
+/* Implement the unwind_sp gdbarch method.  */
+
+static CORE_ADDR
+nios2_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame)
+{
+  return frame_unwind_register_unsigned (this_frame, NIOS2_SP_REGNUM);
+}
+
+/* Use prologue analysis to fill in the register cache
+   *THIS_PROLOGUE_CACHE for THIS_FRAME.  This function initializes
+   *THIS_PROLOGUE_CACHE first.  */
+
+static struct nios2_unwind_cache *
+nios2_frame_unwind_cache (struct frame_info *this_frame,
+                         void **this_prologue_cache)
+{
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  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.  */
+  nios2_init_cache (cache, get_frame_func (this_frame));
+
+  /* Prologue analysis does the rest...  */
+  current_pc = get_frame_pc (this_frame);
+  if (cache->pc != 0)
+    nios2_analyze_prologue (gdbarch, cache->pc, current_pc, cache, this_frame);
+
+  return cache;
+}
+
+/* Implement the this_id function for the normal unwinder.  */
+
+static void
+nios2_frame_this_id (struct frame_info *this_frame, void **this_cache,
+                    struct frame_id *this_id)
+{
+  struct nios2_unwind_cache *cache =
+    nios2_frame_unwind_cache (this_frame, this_cache);
+
+  /* This marks the outermost frame.  */
+  if (cache->base == 0)
+    return;
+
+  *this_id = frame_id_build (cache->cfa, cache->pc);
+}
+
+/* Implement the prev_register function for the normal unwinder.  */
+
+static struct value *
+nios2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+                          int regnum)
+{
+  struct nios2_unwind_cache *cache =
+    nios2_frame_unwind_cache (this_frame, this_cache);
+
+  gdb_assert (regnum >= 0 && regnum < NIOS2_NUM_REGS);
+
+  /* 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 == NIOS2_PC_REGNUM)
+    regnum = cache->return_regnum;
+
+  if (regnum == NIOS2_SP_REGNUM && cache->cfa)
+    return frame_unwind_got_constant (this_frame, regnum, cache->cfa);
+
+  /* If we've worked out where a register is stored then load it from
+     there.  */
+  if (cache->reg_saved[regnum].basereg == NIOS2_Z_REGNUM)
+    return frame_unwind_got_memory (this_frame, regnum,
+                                   cache->reg_saved[regnum].addr);
+
+  return frame_unwind_got_register (this_frame, regnum, regnum);
+}
+
+/* Implement the this_base, this_locals, and this_args hooks
+   for the normal unwinder.  */
+
+static CORE_ADDR
+nios2_frame_base_address (struct frame_info *this_frame, void **this_cache)
+{
+  struct nios2_unwind_cache *info
+    = nios2_frame_unwind_cache (this_frame, this_cache);
+
+  return info->base;
+}
+
+/* Data structures for the normal prologue-analysis-based
+   unwinder.  */
+
+static const struct frame_unwind nios2_frame_unwind =
+{
+  NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
+  nios2_frame_this_id,
+  nios2_frame_prev_register,
+  NULL,
+  default_frame_sniffer
+};
+
+static const struct frame_base nios2_frame_base =
+{
+  &nios2_frame_unwind,
+  nios2_frame_base_address,
+  nios2_frame_base_address,
+  nios2_frame_base_address
+};
+
+/* Fill in the register cache *THIS_CACHE for THIS_FRAME for use
+   in the stub unwinder.  */
+
+static struct trad_frame_cache *
+nios2_stub_frame_cache (struct frame_info *this_frame, void **this_cache)
+{
+  CORE_ADDR pc;
+  CORE_ADDR start_addr;
+  CORE_ADDR stack_addr;
+  struct trad_frame_cache *this_trad_cache;
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  int num_regs = gdbarch_num_regs (gdbarch);
+
+  if (*this_cache != NULL)
+    return *this_cache;
+  this_trad_cache = trad_frame_cache_zalloc (this_frame);
+  *this_cache = this_trad_cache;
+
+  /* The return address is in the link register.  */
+  trad_frame_set_reg_realreg (this_trad_cache,
+                              gdbarch_pc_regnum (gdbarch),
+                              NIOS2_RA_REGNUM);
+
+  /* Frame ID, since it's a frameless / stackless function, no stack
+     space is allocated and SP on entry is the current SP.  */
+  pc = get_frame_pc (this_frame);
+  find_pc_partial_function (pc, NULL, &start_addr, NULL);
+  stack_addr = get_frame_register_unsigned (this_frame, NIOS2_SP_REGNUM);
+  trad_frame_set_id (this_trad_cache, frame_id_build (start_addr, stack_addr));
+  /* Assume that the frame's base is the same as the stack pointer.  */
+  trad_frame_set_this_base (this_trad_cache, stack_addr);
+
+  return this_trad_cache;
+}
+
+/* Implement the this_id function for the stub unwinder.  */
+
+static void
+nios2_stub_frame_this_id (struct frame_info *this_frame, void **this_cache,
+                          struct frame_id *this_id)
+{
+  struct trad_frame_cache *this_trad_cache
+    = nios2_stub_frame_cache (this_frame, this_cache);
+
+  trad_frame_get_id (this_trad_cache, this_id);
+}
+
+/* Implement the prev_register function for the stub unwinder.  */
+
+static struct value *
+nios2_stub_frame_prev_register (struct frame_info *this_frame,
+                               void **this_cache, int regnum)
+{
+  struct trad_frame_cache *this_trad_cache
+    = nios2_stub_frame_cache (this_frame, this_cache);
+
+  return trad_frame_get_register (this_trad_cache, this_frame, regnum);
+}
+
+/* Implement the sniffer function for the stub unwinder.
+   This unwinder is used for cases where the normal
+   prologue-analysis-based unwinder can't work,
+   such as PLT stubs.  */
+
+static int
+nios2_stub_frame_sniffer (const struct frame_unwind *self,
+                         struct frame_info *this_frame, void **cache)
+{
+  gdb_byte dummy[4];
+  struct obj_section *s;
+  CORE_ADDR pc = get_frame_address_in_block (this_frame);
+
+  /* Use the stub unwinder for unreadable code.  */
+  if (target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0)
+    return 1;
+
+  if (in_plt_section (pc, NULL))
+    return 1;
+
+  return 0;
+}
+
+/* Implement the this_base, this_locals, and this_args hooks
+   for the stub unwinder.  */
+
+static CORE_ADDR
+nios2_stub_frame_base_address (struct frame_info *this_frame, void **this_cache)
+{
+  struct trad_frame_cache *this_trad_cache
+    = nios2_stub_frame_cache (this_frame, this_cache);
+
+  return trad_frame_get_this_base (this_trad_cache);
+}
+
+/* Define the data structures for the stub unwinder.  */
+
+static const struct frame_unwind nios2_stub_frame_unwind =
+{
+  NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
+  nios2_stub_frame_this_id,
+  nios2_stub_frame_prev_register,
+  NULL,
+  nios2_stub_frame_sniffer
+};
+
+static const struct frame_base nios2_stub_frame_base =
+{
+  &nios2_stub_frame_unwind,
+  nios2_stub_frame_base_address,
+  nios2_stub_frame_base_address,
+  nios2_stub_frame_base_address
+};
+
+/* Helper function to read an instruction at PC.  */
+
+static unsigned long
+nios2_fetch_instruction (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+  return read_memory_unsigned_integer (pc, NIOS2_OPCODE_SIZE, byte_order);
+}
+
+/* Determine where to set a single step breakpoint while considering
+   branch prediction.  */
+
+static CORE_ADDR
+nios2_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  unsigned long inst;
+  int op;
+  int imm16;
+  int ra;
+  int rb;
+  int ras;
+  int rbs;
+  unsigned int rau;
+  unsigned int rbu;
+
+  inst = nios2_fetch_instruction (gdbarch, pc);
+  pc += NIOS2_OPCODE_SIZE;
+
+  imm16 = (short) GET_IW_IMM16 (inst);
+  ra = GET_IW_A (inst);
+  rb = GET_IW_B (inst);
+  ras = get_frame_register_signed (frame, ra);
+  rbs = get_frame_register_signed (frame, rb);
+  rau = get_frame_register_unsigned (frame, ra);
+  rbu = get_frame_register_unsigned (frame, rb);
+
+  switch (GET_IW_OP (inst))
+    {
+    case OP_BEQ:
+      if (ras == rbs)
+       pc += imm16;
+      break;
+
+    case OP_BGE:
+      if (ras >= rbs)
+        pc += imm16;
+      break;
+
+    case OP_BGEU:
+      if (rau >= rbu)
+        pc += imm16;
+      break;
+
+    case OP_BLT:
+      if (ras < rbs)
+        pc += imm16;
+      break;
+
+    case OP_BLTU:
+      if (rau < rbu)
+        pc += imm16;
+      break;
+
+    case OP_BNE:
+      if (ras != rbs)
+        pc += imm16;
+      break;
+
+    case OP_BR:
+      pc += imm16;
+      break;
+
+    case OP_JMPI:
+    case OP_CALL:
+      pc = (pc & 0xf0000000) | (GET_IW_IMM26 (inst) << 2);
+      break;
+
+    case OP_OPX:
+      switch (GET_IW_OPX (inst))
+       {
+       case OPX_JMP:
+       case OPX_CALLR:
+       case OPX_RET:
+         pc = ras;
+         break;
+
+       case OPX_TRAP:
+         if (tdep->syscall_next_pc != NULL)
+           return tdep->syscall_next_pc (frame);
+
+       default:
+         break;
+       }
+      break;
+    default:
+      break;
+    }
+  return pc;
+}
+
+/* Implement the software_single_step gdbarch method.  */
+
+static int
+nios2_software_single_step (struct frame_info *frame)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct address_space *aspace = get_frame_address_space (frame);
+  CORE_ADDR next_pc = nios2_get_next_pc (frame, get_frame_pc (frame));
+
+  insert_single_step_breakpoint (gdbarch, aspace, next_pc);
+
+  return 1;
+}
+
+/* Implement the get_longjump_target gdbarch method.  */
+
+static int
+nios2_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  CORE_ADDR jb_addr = get_frame_register_unsigned (frame, NIOS2_R4_REGNUM);
+  gdb_byte buf[4];
+
+  if (target_read_memory (jb_addr + (tdep->jb_pc * 4), buf, 4))
+    return 0;
+
+  *pc = extract_unsigned_integer (buf, 4, byte_order);
+  return 1;
+}
+
+/* Initialize the Nios II gdbarch.  */
+
+static struct gdbarch *
+nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+  struct gdbarch *gdbarch;
+  struct gdbarch_tdep *tdep;
+  int register_bytes, i;
+  struct tdesc_arch_data *tdesc_data = NULL;
+  const struct target_desc *tdesc = info.target_desc;
+
+  if (!tdesc_has_registers (tdesc))
+    /* Pick a default target description.  */
+    tdesc = tdesc_nios2;
+
+  /* Check any target description for validity.  */
+  if (tdesc_has_registers (tdesc))
+    {
+      const struct tdesc_feature *feature;
+      int valid_p;
+
+      feature = tdesc_find_feature (tdesc, "org.gnu.gdb.nios2.cpu");
+      if (feature == NULL)
+       return NULL;
+
+      tdesc_data = tdesc_data_alloc ();
+
+      valid_p = 1;
+      
+      for (i = 0; i < NIOS2_NUM_REGS; i++)
+       valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+                                           nios2_reg_names[i]);
+
+      if (!valid_p)
+       {
+         tdesc_data_cleanup (tdesc_data);
+         return NULL;
+       }
+    }
+
+  /* Find a candidate among the list of pre-declared architectures.  */
+  arches = gdbarch_list_lookup_by_info (arches, &info);
+  if (arches != NULL)
+    return arches->gdbarch;
+
+  /* None found, create a new architecture from the information
+     provided.  */
+  tdep = xcalloc (1, sizeof (struct gdbarch_tdep));
+  gdbarch = gdbarch_alloc (&info, tdep);
+
+  /* longjmp support not enabled by default.  */
+  tdep->jb_pc = -1;
+
+  /* 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);
+
+  set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
+  set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
+
+  /* The register set.  */
+  set_gdbarch_num_regs (gdbarch, NIOS2_NUM_REGS);
+  set_gdbarch_sp_regnum (gdbarch, NIOS2_SP_REGNUM);
+  set_gdbarch_pc_regnum (gdbarch, NIOS2_PC_REGNUM);    /* Pseudo register PC */
+
+  set_gdbarch_register_name (gdbarch, nios2_register_name);
+  set_gdbarch_register_type (gdbarch, nios2_register_type);
+
+  /* Provide register mappings for stabs and dwarf2.  */
+  set_gdbarch_stab_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);
+
+  set_gdbarch_return_value (gdbarch, nios2_return_value);
+
+  set_gdbarch_skip_prologue (gdbarch, nios2_skip_prologue);
+  set_gdbarch_in_function_epilogue_p (gdbarch, nios2_in_function_epilogue_p);
+  set_gdbarch_breakpoint_from_pc (gdbarch, nios2_breakpoint_from_pc);
+
+  set_gdbarch_dummy_id (gdbarch, nios2_dummy_id);
+  set_gdbarch_unwind_pc (gdbarch, nios2_unwind_pc);
+  set_gdbarch_unwind_sp (gdbarch, nios2_unwind_sp);
+
+  /* The dwarf2 unwinder will normally produce the best results if
+     the debug information is available, so register it first.  */
+  dwarf2_append_unwinders (gdbarch);
+  frame_unwind_append_unwinder (gdbarch, &nios2_stub_frame_unwind);
+  frame_unwind_append_unwinder (gdbarch, &nios2_frame_unwind);
+
+  /* Single stepping.  */
+  set_gdbarch_software_single_step (gdbarch, nios2_software_single_step);
+
+  /* Hook in ABI-specific overrides, if they have been registered.  */
+  gdbarch_init_osabi (info, gdbarch);
+
+  if (tdep->jb_pc >= 0)
+    set_gdbarch_get_longjmp_target (gdbarch, nios2_get_longjmp_target);
+
+  frame_base_set_default (gdbarch, &nios2_frame_base);
+
+  set_gdbarch_print_insn (gdbarch, nios2_print_insn);
+
+  /* Enable inferior call support.  */
+  set_gdbarch_push_dummy_call (gdbarch, nios2_push_dummy_call);
+
+  if (tdesc_data)
+    tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+
+  return gdbarch;
+}
+
+extern initialize_file_ftype _initialize_nios2_tdep; /* -Wmissing-prototypes */
+
+void
+_initialize_nios2_tdep (void)
+{
+  gdbarch_register (bfd_arch_nios2, nios2_gdbarch_init, NULL);
+  initialize_tdesc_nios2 ();
+
+  /* Allow debugging this file's internals.  */
+  add_setshow_boolean_cmd ("nios2", class_maintenance, &nios2_debug,
+                          _("Set Nios II debugging."),
+                          _("Show Nios II debugging."),
+                          _("When on, Nios II specific debugging is enabled."),
+                          NULL,
+                          NULL,
+                          &setdebuglist, &showdebuglist);
+}
diff --git a/gdb/nios2-tdep.h b/gdb/nios2-tdep.h
new file mode 100644 (file)
index 0000000..5346b9a
--- /dev/null
@@ -0,0 +1,80 @@
+/* Target-dependent header for the Nios II architecture, for GDB.
+   Copyright (C) 2012-2013 Free Software Foundation, Inc.
+   Contributed by Mentor Graphics, Inc.
+
+   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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef NIOS2_TDEP_H
+#define NIOS2_TDEP_H
+
+/* Registers.  */
+#define NIOS2_Z_REGNUM 0     /* Zero */
+#define NIOS2_R2_REGNUM 2    /* used for return value */
+#define NIOS2_R3_REGNUM 3    /* used for return value */
+/* Used for hidden zero argument to store ptr to struct return value.  */
+#define NIOS2_R4_REGNUM 4
+#define NIOS2_R7_REGNUM 7
+#define NIOS2_GP_REGNUM 26  /* Global Pointer */
+#define NIOS2_SP_REGNUM 27  /* Stack Pointer */
+#define NIOS2_FP_REGNUM 28  /* Frame Pointer */
+#define NIOS2_EA_REGNUM 29  /* Exception address */
+#define NIOS2_BA_REGNUM 30  /* Breakpoint return address */
+#define NIOS2_RA_REGNUM 31  /* Return address */
+#define NIOS2_PC_REGNUM 32
+
+/* Control registers.  */
+#define NIOS2_STATUS_REGNUM 33
+#define NIOS2_ESTATUS_REGNUM 34
+#define NIOS2_BSTATUS_REGNUM 35
+#define NIOS2_IENABLE_REGNUM 36
+#define NIOS2_IPENDING_REGNUM 37
+#define NIOS2_CPUID_REGNUM 38
+#define NIOS2_EXCEPTION_REGNUM 40
+#define NIOS2_PTEADDR_REGNUM 41
+#define NIOS2_TLBACC_REGNUM 42
+#define NIOS2_TLBMISC_REGNUM 43
+#define NIOS2_ECCINJ_REGNUM 44
+#define NIOS2_BADADDR_REGNUM 45
+#define NIOS2_CONFIG_REGNUM 46
+#define NIOS2_MPUBASE_REGNUM 47
+#define NIOS2_MPUACC_REGNUM 48
+
+/* R4-R7 are used for argument passing.  */
+#define NIOS2_FIRST_ARGREG NIOS2_R4_REGNUM
+#define NIOS2_LAST_ARGREG NIOS2_R7_REGNUM
+
+/* Number of all registers.  */
+#define NIOS2_NUM_REGS 49
+
+/* Size of an instruction, in bytes.  */
+#define NIOS2_OPCODE_SIZE 4
+
+/* Target-dependent structure in gdbarch.  */
+struct gdbarch_tdep
+{
+  /* Assumes FRAME is stopped at a syscall (trap) instruction; returns
+     the expected next PC.  */
+  CORE_ADDR (*syscall_next_pc) (struct frame_info *frame);
+
+  /* Offset to PC value in jump buffer.
+     If this is negative, longjmp support will be disabled.  */
+  int jb_pc;
+};
+
+extern struct target_desc *tdesc_nios2_linux;
+extern struct target_desc *tdesc_nios2;
+
+#endif /* NIOS2_TDEP_H */
diff --git a/gdb/regformats/nios2-linux.dat b/gdb/regformats/nios2-linux.dat
new file mode 100644 (file)
index 0000000..0b89d53
--- /dev/null
@@ -0,0 +1,53 @@
+# DO NOT EDIT: generated from nios2-linux.xml
+name:nios2_linux
+xmltarget:nios2-linux.xml
+expedite:sp,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:exception
+32:pteaddr
+32:tlbacc
+32:tlbmisc
+32:eccinj
+32:badaddr
+32:config
+32:mpubase
+32:mpuacc