All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH V2 1/7] nios2: Add disas entries
@ 2016-09-27 23:30 Marek Vasut
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support Marek Vasut
                   ` (6 more replies)
  0 siblings, 7 replies; 21+ messages in thread
From: Marek Vasut @ 2016-09-27 23:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marek Vasut, Chris Wulff, Jeff Da Silva, Ley Foon Tan,
	Sandra Loosemore, Yves Vandervennet

Add nios2 disassembler support. This patch is composed from binutils files
from commit "Opcodes and assembler support for Nios II R2". The files from
binutils used in this patch are:

    include/opcode/nios2.h
    include/opcode/nios2r1.h
    include/opcode/nios2r2.h
    opcodes/nios2-opc.c
    opcodes/nios2-dis.c

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Chris Wulff <crwulff@gmail.com>
Cc: Jeff Da Silva <jdasilva@altera.com>
Cc: Ley Foon Tan <lftan@altera.com>
Cc: Sandra Loosemore <sandra@codesourcery.com>
Cc: Yves Vandervennet <yvanderv@altera.com>
---
V2: Replace the nios2.c with GPL2 licensed version
---
 disas/Makefile.objs |    1 +
 disas/nios2.c       | 3534 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/disas/bfd.h |    6 +
 3 files changed, 3541 insertions(+)
 create mode 100644 disas/nios2.c

diff --git a/disas/Makefile.objs b/disas/Makefile.objs
index 09bc992..ac79d16 100644
--- a/disas/Makefile.objs
+++ b/disas/Makefile.objs
@@ -14,6 +14,7 @@ common-obj-$(CONFIG_IA64_DIS) += ia64.o
 common-obj-$(CONFIG_M68K_DIS) += m68k.o
 common-obj-$(CONFIG_MICROBLAZE_DIS) += microblaze.o
 common-obj-$(CONFIG_MIPS_DIS) += mips.o
+common-obj-$(CONFIG_NIOS2_DIS) += nios2.o
 common-obj-$(CONFIG_MOXIE_DIS) += moxie.o
 common-obj-$(CONFIG_PPC_DIS) += ppc.o
 common-obj-$(CONFIG_S390_DIS) += s390.o
diff --git a/disas/nios2.c b/disas/nios2.c
new file mode 100644
index 0000000..b342936
--- /dev/null
+++ b/disas/nios2.c
@@ -0,0 +1,3534 @@
+/* Nios II opcode library for QEMU.
+   Copyright (C) 2012-2016 Free Software Foundation, Inc.
+   Contributed by Nigel Gray (ngray@altera.com).
+   Contributed by Mentor Graphics, 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., 51 Franklin Street, Fifth Floor,
+   Boston, MA  02110-1301, USA.  */
+
+/* This file resembles a concatenation of the following files from
+   binutils:
+
+   include/opcode/nios2.h
+   include/opcode/nios2r1.h
+   include/opcode/nios2r2.h
+   opcodes/nios2-opc.c
+   opcodes/nios2-dis.c
+
+   It has been derived from the original patches which have been
+   relicensed by the contributors as GPL version 2 for inclusion
+   in QEMU.  */
+
+#ifndef _NIOS2_H_
+#define _NIOS2_H_
+
+/*#include "bfd.h"*/
+#include "qemu/osdep.h"
+#include "disas/bfd.h"
+
+
+/****************************************************************************
+ * This file contains structures, bit masks and shift counts used
+ * by the GNU toolchain to define the Nios II instruction set and
+ * access various opcode fields.
+ ****************************************************************************/
+
+/* Instruction encoding formats.  */
+enum iw_format_type {
+  /* R1 formats.  */
+  iw_i_type,
+  iw_r_type,
+  iw_j_type,
+  iw_custom_type,
+
+  /* 32-bit R2 formats.  */
+  iw_L26_type,
+  iw_F2I16_type,
+  iw_F2X4I12_type,
+  iw_F1X4I12_type,
+  iw_F1X4L17_type,
+  iw_F3X6L5_type,
+  iw_F2X6L10_type,
+  iw_F3X6_type,
+  iw_F3X8_type,
+
+  /* 16-bit R2 formats.  */
+  iw_I10_type,
+  iw_T1I7_type,
+  iw_T2I4_type,
+  iw_T1X1I6_type,
+  iw_X1I7_type,
+  iw_L5I4X1_type,
+  iw_T2X1L3_type,
+  iw_T2X1I3_type,
+  iw_T3X1_type,
+  iw_T2X3_type,
+  iw_F1X1_type,
+  iw_X2L5_type,
+  iw_F1I5_type,
+  iw_F2_type
+};
+
+/* Identify different overflow situations for error messages.  */
+enum overflow_type
+{
+  call_target_overflow = 0,
+  branch_target_overflow,
+  address_offset_overflow,
+  signed_immed16_overflow,
+  unsigned_immed16_overflow,
+  unsigned_immed5_overflow,
+  signed_immed12_overflow,
+  custom_opcode_overflow,
+  enumeration_overflow,
+  no_overflow
+};
+
+/* This structure holds information for a particular instruction. 
+
+   The args field is a string describing the operands.  The following
+   letters can appear in the args:
+     c - a 5-bit control register index
+     d - a 5-bit destination register index
+     s - a 5-bit left source register index
+     t - a 5-bit right source register index
+     D - a 3-bit encoded destination register
+     S - a 3-bit encoded left source register
+     T - a 3-bit encoded right source register
+     i - a 16-bit signed immediate
+     j - a 5-bit unsigned immediate
+     k - a (second) 5-bit unsigned immediate
+     l - a 8-bit custom instruction constant
+     m - a 26-bit unsigned immediate
+     o - a 16-bit signed pc-relative offset
+     u - a 16-bit unsigned immediate
+     I - a 12-bit signed immediate
+     M - a 6-bit unsigned immediate
+     N - a 6-bit unsigned immediate with 2-bit shift
+     O - a 10-bit signed pc-relative offset with 1-bit shift
+     P - a 7-bit signed pc-relative offset with 1-bit shift
+     U - a 7-bit unsigned immediate with 2-bit shift
+     V - a 5-bit unsigned immediate with 2-bit shift
+     W - a 4-bit unsigned immediate with 2-bit shift
+     X - a 4-bit unsigned immediate with 1-bit shift
+     Y - a 4-bit unsigned immediate
+     e - an immediate coded as an enumeration for addi.n/subi.n
+     f - an immediate coded as an enumeration for slli.n/srli.n
+     g - an immediate coded as an enumeration for andi.n
+     h - an immediate coded as an enumeration for movi.n
+     R - a reglist for ldwm/stwm or push.n/pop.n
+     B - a base register specifier and option list for ldwm/stwm
+   Literal ',', '(', and ')' characters may also appear in the args as
+   delimiters.
+
+   Note that the args describe the semantics and assembly-language syntax
+   of the operands, not their encoding into the instruction word.
+
+   The pinfo field is INSN_MACRO for a macro.  Otherwise, it is a collection
+   of bits describing the instruction, notably any relevant hazard
+   information.
+
+   When assembling, the match field contains the opcode template, which
+   is modified by the arguments to produce the actual opcode
+   that is emitted.  If pinfo is INSN_MACRO, then this is 0.
+
+   If pinfo is INSN_MACRO, the mask field stores the macro identifier.
+   Otherwise 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.  */
+
+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 size;		/* Size in bytes of the instruction.  */
+  enum iw_format_type format;	/* Instruction format.  */
+  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;  /* 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_OPTARG	0x00000080
+
+/* Register attributes.  */
+#define REG_NORMAL	(1<<0)	/* Normal registers.  */
+#define REG_CONTROL	(1<<1)  /* Control registers.  */
+#define REG_COPROCESSOR	(1<<2)  /* For custom instructions.  */
+#define REG_3BIT	(1<<3)  /* For R2 CDX instructions.  */
+#define REG_LDWM	(1<<4)  /* For R2 ldwm/stwm.  */
+#define REG_POP		(1<<5)  /* For R2 pop.n/push.n.  */
+
+struct nios2_reg
+{
+  const char *name;
+  const int index;
+  unsigned long regtype;
+};
+
+/* Pull in the instruction field accessors, opcodes, and masks.  */
+/*#include "nios2r1.h"*/
+
+#ifndef _NIOS2R1_H_
+#define _NIOS2R1_H_
+
+/* R1 fields.  */
+#define IW_R1_OP_LSB 0 
+#define IW_R1_OP_SIZE 6 
+#define IW_R1_OP_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R1_OP_SIZE)) 
+#define IW_R1_OP_SHIFTED_MASK (IW_R1_OP_UNSHIFTED_MASK << IW_R1_OP_LSB) 
+#define GET_IW_R1_OP(W) (((W) >> IW_R1_OP_LSB) & IW_R1_OP_UNSHIFTED_MASK) 
+#define SET_IW_R1_OP(V) (((V) & IW_R1_OP_UNSHIFTED_MASK) << IW_R1_OP_LSB) 
+
+#define IW_I_A_LSB 27 
+#define IW_I_A_SIZE 5 
+#define IW_I_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_I_A_SIZE)) 
+#define IW_I_A_SHIFTED_MASK (IW_I_A_UNSHIFTED_MASK << IW_I_A_LSB) 
+#define GET_IW_I_A(W) (((W) >> IW_I_A_LSB) & IW_I_A_UNSHIFTED_MASK) 
+#define SET_IW_I_A(V) (((V) & IW_I_A_UNSHIFTED_MASK) << IW_I_A_LSB) 
+
+#define IW_I_B_LSB 22 
+#define IW_I_B_SIZE 5 
+#define IW_I_B_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_I_B_SIZE)) 
+#define IW_I_B_SHIFTED_MASK (IW_I_B_UNSHIFTED_MASK << IW_I_B_LSB) 
+#define GET_IW_I_B(W) (((W) >> IW_I_B_LSB) & IW_I_B_UNSHIFTED_MASK) 
+#define SET_IW_I_B(V) (((V) & IW_I_B_UNSHIFTED_MASK) << IW_I_B_LSB) 
+
+#define IW_I_IMM16_LSB 6 
+#define IW_I_IMM16_SIZE 16 
+#define IW_I_IMM16_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_I_IMM16_SIZE)) 
+#define IW_I_IMM16_SHIFTED_MASK (IW_I_IMM16_UNSHIFTED_MASK << IW_I_IMM16_LSB) 
+#define GET_IW_I_IMM16(W) (((W) >> IW_I_IMM16_LSB) & IW_I_IMM16_UNSHIFTED_MASK) 
+#define SET_IW_I_IMM16(V) (((V) & IW_I_IMM16_UNSHIFTED_MASK) << IW_I_IMM16_LSB) 
+
+#define IW_R_A_LSB 27 
+#define IW_R_A_SIZE 5 
+#define IW_R_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R_A_SIZE)) 
+#define IW_R_A_SHIFTED_MASK (IW_R_A_UNSHIFTED_MASK << IW_R_A_LSB) 
+#define GET_IW_R_A(W) (((W) >> IW_R_A_LSB) & IW_R_A_UNSHIFTED_MASK) 
+#define SET_IW_R_A(V) (((V) & IW_R_A_UNSHIFTED_MASK) << IW_R_A_LSB) 
+
+#define IW_R_B_LSB 22 
+#define IW_R_B_SIZE 5 
+#define IW_R_B_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R_B_SIZE)) 
+#define IW_R_B_SHIFTED_MASK (IW_R_B_UNSHIFTED_MASK << IW_R_B_LSB) 
+#define GET_IW_R_B(W) (((W) >> IW_R_B_LSB) & IW_R_B_UNSHIFTED_MASK) 
+#define SET_IW_R_B(V) (((V) & IW_R_B_UNSHIFTED_MASK) << IW_R_B_LSB) 
+
+#define IW_R_C_LSB 17 
+#define IW_R_C_SIZE 5 
+#define IW_R_C_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R_C_SIZE)) 
+#define IW_R_C_SHIFTED_MASK (IW_R_C_UNSHIFTED_MASK << IW_R_C_LSB) 
+#define GET_IW_R_C(W) (((W) >> IW_R_C_LSB) & IW_R_C_UNSHIFTED_MASK) 
+#define SET_IW_R_C(V) (((V) & IW_R_C_UNSHIFTED_MASK) << IW_R_C_LSB) 
+
+#define IW_R_OPX_LSB 11 
+#define IW_R_OPX_SIZE 6 
+#define IW_R_OPX_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R_OPX_SIZE)) 
+#define IW_R_OPX_SHIFTED_MASK (IW_R_OPX_UNSHIFTED_MASK << IW_R_OPX_LSB) 
+#define GET_IW_R_OPX(W) (((W) >> IW_R_OPX_LSB) & IW_R_OPX_UNSHIFTED_MASK) 
+#define SET_IW_R_OPX(V) (((V) & IW_R_OPX_UNSHIFTED_MASK) << IW_R_OPX_LSB) 
+
+#define IW_R_IMM5_LSB 6 
+#define IW_R_IMM5_SIZE 5 
+#define IW_R_IMM5_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R_IMM5_SIZE)) 
+#define IW_R_IMM5_SHIFTED_MASK (IW_R_IMM5_UNSHIFTED_MASK << IW_R_IMM5_LSB) 
+#define GET_IW_R_IMM5(W) (((W) >> IW_R_IMM5_LSB) & IW_R_IMM5_UNSHIFTED_MASK) 
+#define SET_IW_R_IMM5(V) (((V) & IW_R_IMM5_UNSHIFTED_MASK) << IW_R_IMM5_LSB) 
+
+#define IW_J_IMM26_LSB 6 
+#define IW_J_IMM26_SIZE 26 
+#define IW_J_IMM26_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_J_IMM26_SIZE)) 
+#define IW_J_IMM26_SHIFTED_MASK (IW_J_IMM26_UNSHIFTED_MASK << IW_J_IMM26_LSB) 
+#define GET_IW_J_IMM26(W) (((W) >> IW_J_IMM26_LSB) & IW_J_IMM26_UNSHIFTED_MASK) 
+#define SET_IW_J_IMM26(V) (((V) & IW_J_IMM26_UNSHIFTED_MASK) << IW_J_IMM26_LSB) 
+
+#define IW_CUSTOM_A_LSB 27 
+#define IW_CUSTOM_A_SIZE 5 
+#define IW_CUSTOM_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_A_SIZE)) 
+#define IW_CUSTOM_A_SHIFTED_MASK (IW_CUSTOM_A_UNSHIFTED_MASK << IW_CUSTOM_A_LSB) 
+#define GET_IW_CUSTOM_A(W) (((W) >> IW_CUSTOM_A_LSB) & IW_CUSTOM_A_UNSHIFTED_MASK) 
+#define SET_IW_CUSTOM_A(V) (((V) & IW_CUSTOM_A_UNSHIFTED_MASK) << IW_CUSTOM_A_LSB) 
+
+#define IW_CUSTOM_B_LSB 22 
+#define IW_CUSTOM_B_SIZE 5 
+#define IW_CUSTOM_B_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_B_SIZE)) 
+#define IW_CUSTOM_B_SHIFTED_MASK (IW_CUSTOM_B_UNSHIFTED_MASK << IW_CUSTOM_B_LSB) 
+#define GET_IW_CUSTOM_B(W) (((W) >> IW_CUSTOM_B_LSB) & IW_CUSTOM_B_UNSHIFTED_MASK) 
+#define SET_IW_CUSTOM_B(V) (((V) & IW_CUSTOM_B_UNSHIFTED_MASK) << IW_CUSTOM_B_LSB) 
+
+#define IW_CUSTOM_C_LSB 17 
+#define IW_CUSTOM_C_SIZE 5 
+#define IW_CUSTOM_C_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_C_SIZE)) 
+#define IW_CUSTOM_C_SHIFTED_MASK (IW_CUSTOM_C_UNSHIFTED_MASK << IW_CUSTOM_C_LSB) 
+#define GET_IW_CUSTOM_C(W) (((W) >> IW_CUSTOM_C_LSB) & IW_CUSTOM_C_UNSHIFTED_MASK) 
+#define SET_IW_CUSTOM_C(V) (((V) & IW_CUSTOM_C_UNSHIFTED_MASK) << IW_CUSTOM_C_LSB) 
+
+#define IW_CUSTOM_READA_LSB 16 
+#define IW_CUSTOM_READA_SIZE 1 
+#define IW_CUSTOM_READA_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_READA_SIZE)) 
+#define IW_CUSTOM_READA_SHIFTED_MASK (IW_CUSTOM_READA_UNSHIFTED_MASK << IW_CUSTOM_READA_LSB) 
+#define GET_IW_CUSTOM_READA(W) (((W) >> IW_CUSTOM_READA_LSB) & IW_CUSTOM_READA_UNSHIFTED_MASK) 
+#define SET_IW_CUSTOM_READA(V) (((V) & IW_CUSTOM_READA_UNSHIFTED_MASK) << IW_CUSTOM_READA_LSB) 
+
+#define IW_CUSTOM_READB_LSB 15 
+#define IW_CUSTOM_READB_SIZE 1 
+#define IW_CUSTOM_READB_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_READB_SIZE)) 
+#define IW_CUSTOM_READB_SHIFTED_MASK (IW_CUSTOM_READB_UNSHIFTED_MASK << IW_CUSTOM_READB_LSB) 
+#define GET_IW_CUSTOM_READB(W) (((W) >> IW_CUSTOM_READB_LSB) & IW_CUSTOM_READB_UNSHIFTED_MASK) 
+#define SET_IW_CUSTOM_READB(V) (((V) & IW_CUSTOM_READB_UNSHIFTED_MASK) << IW_CUSTOM_READB_LSB) 
+
+#define IW_CUSTOM_READC_LSB 14 
+#define IW_CUSTOM_READC_SIZE 1 
+#define IW_CUSTOM_READC_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_READC_SIZE)) 
+#define IW_CUSTOM_READC_SHIFTED_MASK (IW_CUSTOM_READC_UNSHIFTED_MASK << IW_CUSTOM_READC_LSB) 
+#define GET_IW_CUSTOM_READC(W) (((W) >> IW_CUSTOM_READC_LSB) & IW_CUSTOM_READC_UNSHIFTED_MASK) 
+#define SET_IW_CUSTOM_READC(V) (((V) & IW_CUSTOM_READC_UNSHIFTED_MASK) << IW_CUSTOM_READC_LSB) 
+
+#define IW_CUSTOM_N_LSB 6 
+#define IW_CUSTOM_N_SIZE 8 
+#define IW_CUSTOM_N_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_N_SIZE)) 
+#define IW_CUSTOM_N_SHIFTED_MASK (IW_CUSTOM_N_UNSHIFTED_MASK << IW_CUSTOM_N_LSB) 
+#define GET_IW_CUSTOM_N(W) (((W) >> IW_CUSTOM_N_LSB) & IW_CUSTOM_N_UNSHIFTED_MASK) 
+#define SET_IW_CUSTOM_N(V) (((V) & IW_CUSTOM_N_UNSHIFTED_MASK) << IW_CUSTOM_N_LSB) 
+
+/* R1 opcodes.  */
+#define R1_OP_CALL 0
+#define R1_OP_JMPI 1
+#define R1_OP_LDBU 3
+#define R1_OP_ADDI 4
+#define R1_OP_STB 5
+#define R1_OP_BR 6
+#define R1_OP_LDB 7
+#define R1_OP_CMPGEI 8
+#define R1_OP_LDHU 11
+#define R1_OP_ANDI 12
+#define R1_OP_STH 13
+#define R1_OP_BGE 14
+#define R1_OP_LDH 15
+#define R1_OP_CMPLTI 16
+#define R1_OP_INITDA 19
+#define R1_OP_ORI 20
+#define R1_OP_STW 21
+#define R1_OP_BLT 22
+#define R1_OP_LDW 23
+#define R1_OP_CMPNEI 24
+#define R1_OP_FLUSHDA 27
+#define R1_OP_XORI 28
+#define R1_OP_BNE 30
+#define R1_OP_CMPEQI 32
+#define R1_OP_LDBUIO 35
+#define R1_OP_MULI 36
+#define R1_OP_STBIO 37
+#define R1_OP_BEQ 38
+#define R1_OP_LDBIO 39
+#define R1_OP_CMPGEUI 40
+#define R1_OP_LDHUIO 43
+#define R1_OP_ANDHI 44
+#define R1_OP_STHIO 45
+#define R1_OP_BGEU 46
+#define R1_OP_LDHIO 47
+#define R1_OP_CMPLTUI 48
+#define R1_OP_CUSTOM 50
+#define R1_OP_INITD 51
+#define R1_OP_ORHI 52
+#define R1_OP_STWIO 53
+#define R1_OP_BLTU 54
+#define R1_OP_LDWIO 55
+#define R1_OP_RDPRS 56
+#define R1_OP_OPX 58
+#define R1_OP_FLUSHD 59
+#define R1_OP_XORHI 60
+
+#define R1_OPX_ERET 1
+#define R1_OPX_ROLI 2
+#define R1_OPX_ROL 3
+#define R1_OPX_FLUSHP 4
+#define R1_OPX_RET 5
+#define R1_OPX_NOR 6
+#define R1_OPX_MULXUU 7
+#define R1_OPX_CMPGE 8
+#define R1_OPX_BRET 9
+#define R1_OPX_ROR 11
+#define R1_OPX_FLUSHI 12
+#define R1_OPX_JMP 13
+#define R1_OPX_AND 14
+#define R1_OPX_CMPLT 16
+#define R1_OPX_SLLI 18
+#define R1_OPX_SLL 19
+#define R1_OPX_WRPRS 20
+#define R1_OPX_OR 22
+#define R1_OPX_MULXSU 23
+#define R1_OPX_CMPNE 24
+#define R1_OPX_SRLI 26
+#define R1_OPX_SRL 27
+#define R1_OPX_NEXTPC 28
+#define R1_OPX_CALLR 29
+#define R1_OPX_XOR 30
+#define R1_OPX_MULXSS 31
+#define R1_OPX_CMPEQ 32
+#define R1_OPX_DIVU 36
+#define R1_OPX_DIV 37
+#define R1_OPX_RDCTL 38
+#define R1_OPX_MUL 39
+#define R1_OPX_CMPGEU 40
+#define R1_OPX_INITI 41
+#define R1_OPX_TRAP 45
+#define R1_OPX_WRCTL 46
+#define R1_OPX_CMPLTU 48
+#define R1_OPX_ADD 49
+#define R1_OPX_BREAK 52
+#define R1_OPX_SYNC 54
+#define R1_OPX_SUB 57
+#define R1_OPX_SRAI 58
+#define R1_OPX_SRA 59
+
+/* Some convenience macros for R1 encodings, for use in instruction tables.
+   MATCH_R1_OPX0(NAME) and MASK_R1_OPX0 are used for R-type instructions
+   with 3 register operands and constant 0 in the immediate field.
+   The general forms are MATCH_R1_OPX(NAME, A, B, C) where the arguments specify
+   constant values and MASK_R1_OPX(A, B, C, N) where the arguments are booleans
+   that are true if the field should be included in the mask.
+ */
+#define MATCH_R1_OP(NAME) \
+  (SET_IW_R1_OP (R1_OP_##NAME))
+#define MASK_R1_OP \
+  IW_R1_OP_SHIFTED_MASK
+
+#define MATCH_R1_OPX0(NAME) \
+  (SET_IW_R1_OP (R1_OP_OPX) | SET_IW_R_OPX (R1_OPX_##NAME))
+#define MASK_R1_OPX0 \
+  (IW_R1_OP_SHIFTED_MASK | IW_R_OPX_SHIFTED_MASK | IW_R_IMM5_SHIFTED_MASK)
+
+#define MATCH_R1_OPX(NAME, A, B, C)				\
+  (MATCH_R1_OPX0 (NAME) | SET_IW_R_A (A) | SET_IW_R_B (B) | SET_IW_R_C (C))
+#define MASK_R1_OPX(A, B, C, N)				\
+  (IW_R1_OP_SHIFTED_MASK | IW_R_OPX_SHIFTED_MASK	\
+   | (A ? IW_R_A_SHIFTED_MASK : 0)			\
+   | (B ? IW_R_B_SHIFTED_MASK : 0)			\
+   | (C ? IW_R_C_SHIFTED_MASK : 0)			\
+   | (N ? IW_R_IMM5_SHIFTED_MASK : 0))
+
+/* And here's the match/mask macros for the R1 instruction set.  */
+#define MATCH_R1_ADD	MATCH_R1_OPX0 (ADD)
+#define MASK_R1_ADD	MASK_R1_OPX0
+#define MATCH_R1_ADDI	MATCH_R1_OP (ADDI)
+#define MASK_R1_ADDI	MASK_R1_OP
+#define MATCH_R1_AND	MATCH_R1_OPX0 (AND)
+#define MASK_R1_AND	MASK_R1_OPX0
+#define MATCH_R1_ANDHI	MATCH_R1_OP (ANDHI)
+#define MASK_R1_ANDHI	MASK_R1_OP
+#define MATCH_R1_ANDI	MATCH_R1_OP (ANDI)
+#define MASK_R1_ANDI	MASK_R1_OP
+#define MATCH_R1_BEQ	MATCH_R1_OP (BEQ)
+#define MASK_R1_BEQ	MASK_R1_OP
+#define MATCH_R1_BGE	MATCH_R1_OP (BGE)
+#define MASK_R1_BGE	MASK_R1_OP
+#define MATCH_R1_BGEU	MATCH_R1_OP (BGEU)
+#define MASK_R1_BGEU	MASK_R1_OP
+#define MATCH_R1_BGT	MATCH_R1_OP (BLT)
+#define MASK_R1_BGT	MASK_R1_OP
+#define MATCH_R1_BGTU	MATCH_R1_OP (BLTU)
+#define MASK_R1_BGTU	MASK_R1_OP
+#define MATCH_R1_BLE	MATCH_R1_OP (BGE)
+#define MASK_R1_BLE	MASK_R1_OP
+#define MATCH_R1_BLEU	MATCH_R1_OP (BGEU)
+#define MASK_R1_BLEU	MASK_R1_OP
+#define MATCH_R1_BLT	MATCH_R1_OP (BLT)
+#define MASK_R1_BLT	MASK_R1_OP
+#define MATCH_R1_BLTU	MATCH_R1_OP (BLTU)
+#define MASK_R1_BLTU	MASK_R1_OP
+#define MATCH_R1_BNE	MATCH_R1_OP (BNE)
+#define MASK_R1_BNE	MASK_R1_OP
+#define MATCH_R1_BR	MATCH_R1_OP (BR)
+#define MASK_R1_BR	MASK_R1_OP | IW_I_A_SHIFTED_MASK | IW_I_B_SHIFTED_MASK
+#define MATCH_R1_BREAK	MATCH_R1_OPX (BREAK, 0, 0, 0x1e)
+#define MASK_R1_BREAK	MASK_R1_OPX (1, 1, 1, 0)
+#define MATCH_R1_BRET	MATCH_R1_OPX (BRET, 0x1e, 0, 0)
+#define MASK_R1_BRET	MASK_R1_OPX (1, 1, 1, 1)
+#define MATCH_R1_CALL	MATCH_R1_OP (CALL)
+#define MASK_R1_CALL	MASK_R1_OP
+#define MATCH_R1_CALLR	MATCH_R1_OPX (CALLR, 0, 0, 0x1f)
+#define MASK_R1_CALLR	MASK_R1_OPX (0, 1, 1, 1)
+#define MATCH_R1_CMPEQ	MATCH_R1_OPX0 (CMPEQ)
+#define MASK_R1_CMPEQ	MASK_R1_OPX0
+#define MATCH_R1_CMPEQI	MATCH_R1_OP (CMPEQI)
+#define MASK_R1_CMPEQI	MASK_R1_OP
+#define MATCH_R1_CMPGE	MATCH_R1_OPX0 (CMPGE)
+#define MASK_R1_CMPGE	MASK_R1_OPX0
+#define MATCH_R1_CMPGEI	MATCH_R1_OP (CMPGEI)
+#define MASK_R1_CMPGEI	MASK_R1_OP
+#define MATCH_R1_CMPGEU	MATCH_R1_OPX0 (CMPGEU)
+#define MASK_R1_CMPGEU	MASK_R1_OPX0
+#define MATCH_R1_CMPGEUI	MATCH_R1_OP (CMPGEUI)
+#define MASK_R1_CMPGEUI	MASK_R1_OP
+#define MATCH_R1_CMPGT	MATCH_R1_OPX0 (CMPLT)
+#define MASK_R1_CMPGT	MASK_R1_OPX0
+#define MATCH_R1_CMPGTI	MATCH_R1_OP (CMPGEI)
+#define MASK_R1_CMPGTI	MASK_R1_OP
+#define MATCH_R1_CMPGTU	MATCH_R1_OPX0 (CMPLTU)
+#define MASK_R1_CMPGTU	MASK_R1_OPX0
+#define MATCH_R1_CMPGTUI	MATCH_R1_OP (CMPGEUI)
+#define MASK_R1_CMPGTUI	MASK_R1_OP
+#define MATCH_R1_CMPLE	MATCH_R1_OPX0 (CMPGE)
+#define MASK_R1_CMPLE	MASK_R1_OPX0
+#define MATCH_R1_CMPLEI	MATCH_R1_OP (CMPLTI)
+#define MASK_R1_CMPLEI	MASK_R1_OP
+#define MATCH_R1_CMPLEU	MATCH_R1_OPX0 (CMPGEU)
+#define MASK_R1_CMPLEU	MASK_R1_OPX0
+#define MATCH_R1_CMPLEUI	MATCH_R1_OP (CMPLTUI)
+#define MASK_R1_CMPLEUI	MASK_R1_OP
+#define MATCH_R1_CMPLT	MATCH_R1_OPX0 (CMPLT)
+#define MASK_R1_CMPLT	MASK_R1_OPX0
+#define MATCH_R1_CMPLTI	MATCH_R1_OP (CMPLTI)
+#define MASK_R1_CMPLTI	MASK_R1_OP
+#define MATCH_R1_CMPLTU	MATCH_R1_OPX0 (CMPLTU)
+#define MASK_R1_CMPLTU	MASK_R1_OPX0
+#define MATCH_R1_CMPLTUI	MATCH_R1_OP (CMPLTUI)
+#define MASK_R1_CMPLTUI	MASK_R1_OP
+#define MATCH_R1_CMPNE	MATCH_R1_OPX0 (CMPNE)
+#define MASK_R1_CMPNE	MASK_R1_OPX0
+#define MATCH_R1_CMPNEI	MATCH_R1_OP (CMPNEI)
+#define MASK_R1_CMPNEI	MASK_R1_OP
+#define MATCH_R1_CUSTOM	MATCH_R1_OP (CUSTOM)
+#define MASK_R1_CUSTOM	MASK_R1_OP
+#define MATCH_R1_DIV	MATCH_R1_OPX0 (DIV)
+#define MASK_R1_DIV	MASK_R1_OPX0
+#define MATCH_R1_DIVU	MATCH_R1_OPX0 (DIVU)
+#define MASK_R1_DIVU	MASK_R1_OPX0
+#define MATCH_R1_ERET	MATCH_R1_OPX (ERET, 0x1d, 0x1e, 0)
+#define MASK_R1_ERET	MASK_R1_OPX (1, 1, 1, 1)
+#define MATCH_R1_FLUSHD	MATCH_R1_OP (FLUSHD) | SET_IW_I_B (0)
+#define MASK_R1_FLUSHD	MASK_R1_OP | IW_I_B_SHIFTED_MASK
+#define MATCH_R1_FLUSHDA	MATCH_R1_OP (FLUSHDA) | SET_IW_I_B (0)
+#define MASK_R1_FLUSHDA	MASK_R1_OP | IW_I_B_SHIFTED_MASK
+#define MATCH_R1_FLUSHI	MATCH_R1_OPX (FLUSHI, 0, 0, 0)
+#define MASK_R1_FLUSHI	MASK_R1_OPX (0, 1, 1, 1)
+#define MATCH_R1_FLUSHP	MATCH_R1_OPX (FLUSHP, 0, 0, 0)
+#define MASK_R1_FLUSHP	MASK_R1_OPX (1, 1, 1, 1)
+#define MATCH_R1_INITD	MATCH_R1_OP (INITD) | SET_IW_I_B (0)
+#define MASK_R1_INITD	MASK_R1_OP | IW_I_B_SHIFTED_MASK
+#define MATCH_R1_INITDA	MATCH_R1_OP (INITDA) | SET_IW_I_B (0)
+#define MASK_R1_INITDA	MASK_R1_OP | IW_I_B_SHIFTED_MASK
+#define MATCH_R1_INITI	MATCH_R1_OPX (INITI, 0, 0, 0)
+#define MASK_R1_INITI	MASK_R1_OPX (0, 1, 1, 1)
+#define MATCH_R1_JMP	MATCH_R1_OPX (JMP, 0, 0, 0)
+#define MASK_R1_JMP	MASK_R1_OPX (0, 1, 1, 1)
+#define MATCH_R1_JMPI	MATCH_R1_OP (JMPI)
+#define MASK_R1_JMPI	MASK_R1_OP
+#define MATCH_R1_LDB	MATCH_R1_OP (LDB)
+#define MASK_R1_LDB	MASK_R1_OP
+#define MATCH_R1_LDBIO	MATCH_R1_OP (LDBIO)
+#define MASK_R1_LDBIO	MASK_R1_OP
+#define MATCH_R1_LDBU	MATCH_R1_OP (LDBU)
+#define MASK_R1_LDBU	MASK_R1_OP
+#define MATCH_R1_LDBUIO	MATCH_R1_OP (LDBUIO)
+#define MASK_R1_LDBUIO	MASK_R1_OP
+#define MATCH_R1_LDH	MATCH_R1_OP (LDH)
+#define MASK_R1_LDH	MASK_R1_OP
+#define MATCH_R1_LDHIO	MATCH_R1_OP (LDHIO)
+#define MASK_R1_LDHIO	MASK_R1_OP
+#define MATCH_R1_LDHU	MATCH_R1_OP (LDHU)
+#define MASK_R1_LDHU	MASK_R1_OP
+#define MATCH_R1_LDHUIO	MATCH_R1_OP (LDHUIO)
+#define MASK_R1_LDHUIO	MASK_R1_OP
+#define MATCH_R1_LDW	MATCH_R1_OP (LDW)
+#define MASK_R1_LDW	MASK_R1_OP
+#define MATCH_R1_LDWIO	MATCH_R1_OP (LDWIO)
+#define MASK_R1_LDWIO	MASK_R1_OP
+#define MATCH_R1_MOV	MATCH_R1_OPX (ADD, 0, 0, 0)
+#define MASK_R1_MOV	MASK_R1_OPX (0, 1, 0, 1)
+#define MATCH_R1_MOVHI	MATCH_R1_OP (ORHI) | SET_IW_I_A (0)
+#define MASK_R1_MOVHI	MASK_R1_OP | IW_I_A_SHIFTED_MASK
+#define MATCH_R1_MOVI	MATCH_R1_OP (ADDI) | SET_IW_I_A (0)
+#define MASK_R1_MOVI	MASK_R1_OP | IW_I_A_SHIFTED_MASK
+#define MATCH_R1_MOVUI	MATCH_R1_OP (ORI) | SET_IW_I_A (0)
+#define MASK_R1_MOVUI	MASK_R1_OP | IW_I_A_SHIFTED_MASK
+#define MATCH_R1_MUL	MATCH_R1_OPX0 (MUL)
+#define MASK_R1_MUL	MASK_R1_OPX0
+#define MATCH_R1_MULI	MATCH_R1_OP (MULI)
+#define MASK_R1_MULI	MASK_R1_OP
+#define MATCH_R1_MULXSS	MATCH_R1_OPX0 (MULXSS)
+#define MASK_R1_MULXSS	MASK_R1_OPX0
+#define MATCH_R1_MULXSU	MATCH_R1_OPX0 (MULXSU)
+#define MASK_R1_MULXSU	MASK_R1_OPX0
+#define MATCH_R1_MULXUU	MATCH_R1_OPX0 (MULXUU)
+#define MASK_R1_MULXUU	MASK_R1_OPX0
+#define MATCH_R1_NEXTPC	MATCH_R1_OPX (NEXTPC, 0, 0, 0)
+#define MASK_R1_NEXTPC	MASK_R1_OPX (1, 1, 0, 1)
+#define MATCH_R1_NOP	MATCH_R1_OPX (ADD, 0, 0, 0)
+#define MASK_R1_NOP	MASK_R1_OPX (1, 1, 1, 1)
+#define MATCH_R1_NOR	MATCH_R1_OPX0 (NOR)
+#define MASK_R1_NOR	MASK_R1_OPX0
+#define MATCH_R1_OR	MATCH_R1_OPX0 (OR)
+#define MASK_R1_OR	MASK_R1_OPX0
+#define MATCH_R1_ORHI	MATCH_R1_OP (ORHI)
+#define MASK_R1_ORHI	MASK_R1_OP
+#define MATCH_R1_ORI	MATCH_R1_OP (ORI)
+#define MASK_R1_ORI	MASK_R1_OP
+#define MATCH_R1_RDCTL	MATCH_R1_OPX (RDCTL, 0, 0, 0)
+#define MASK_R1_RDCTL	MASK_R1_OPX (1, 1, 0, 0)
+#define MATCH_R1_RDPRS	MATCH_R1_OP (RDPRS)
+#define MASK_R1_RDPRS	MASK_R1_OP
+#define MATCH_R1_RET	MATCH_R1_OPX (RET, 0x1f, 0, 0)
+#define MASK_R1_RET	MASK_R1_OPX (1, 1, 1, 1)
+#define MATCH_R1_ROL	MATCH_R1_OPX0 (ROL)
+#define MASK_R1_ROL	MASK_R1_OPX0
+#define MATCH_R1_ROLI	MATCH_R1_OPX (ROLI, 0, 0, 0)
+#define MASK_R1_ROLI	MASK_R1_OPX (0, 1, 0, 0)
+#define MATCH_R1_ROR	MATCH_R1_OPX0 (ROR)
+#define MASK_R1_ROR	MASK_R1_OPX0
+#define MATCH_R1_SLL	MATCH_R1_OPX0 (SLL)
+#define MASK_R1_SLL	MASK_R1_OPX0
+#define MATCH_R1_SLLI	MATCH_R1_OPX (SLLI, 0, 0, 0)
+#define MASK_R1_SLLI	MASK_R1_OPX (0, 1, 0, 0)
+#define MATCH_R1_SRA	MATCH_R1_OPX0 (SRA)
+#define MASK_R1_SRA	MASK_R1_OPX0
+#define MATCH_R1_SRAI	MATCH_R1_OPX (SRAI, 0, 0, 0)
+#define MASK_R1_SRAI	MASK_R1_OPX (0, 1, 0, 0)
+#define MATCH_R1_SRL	MATCH_R1_OPX0 (SRL)
+#define MASK_R1_SRL	MASK_R1_OPX0
+#define MATCH_R1_SRLI	MATCH_R1_OPX (SRLI, 0, 0, 0)
+#define MASK_R1_SRLI	MASK_R1_OPX (0, 1, 0, 0)
+#define MATCH_R1_STB	MATCH_R1_OP (STB)
+#define MASK_R1_STB	MASK_R1_OP
+#define MATCH_R1_STBIO	MATCH_R1_OP (STBIO)
+#define MASK_R1_STBIO	MASK_R1_OP
+#define MATCH_R1_STH	MATCH_R1_OP (STH)
+#define MASK_R1_STH	MASK_R1_OP
+#define MATCH_R1_STHIO	MATCH_R1_OP (STHIO)
+#define MASK_R1_STHIO	MASK_R1_OP
+#define MATCH_R1_STW	MATCH_R1_OP (STW)
+#define MASK_R1_STW	MASK_R1_OP
+#define MATCH_R1_STWIO	MATCH_R1_OP (STWIO)
+#define MASK_R1_STWIO	MASK_R1_OP
+#define MATCH_R1_SUB	MATCH_R1_OPX0 (SUB)
+#define MASK_R1_SUB	MASK_R1_OPX0
+#define MATCH_R1_SUBI	MATCH_R1_OP (ADDI)
+#define MASK_R1_SUBI	MASK_R1_OP
+#define MATCH_R1_SYNC	MATCH_R1_OPX (SYNC, 0, 0, 0)
+#define MASK_R1_SYNC	MASK_R1_OPX (1, 1, 1, 1)
+#define MATCH_R1_TRAP	MATCH_R1_OPX (TRAP, 0, 0, 0x1d)
+#define MASK_R1_TRAP	MASK_R1_OPX (1, 1, 1, 0)
+#define MATCH_R1_WRCTL	MATCH_R1_OPX (WRCTL, 0, 0, 0)
+#define MASK_R1_WRCTL	MASK_R1_OPX (0, 1, 1, 0)
+#define MATCH_R1_WRPRS	MATCH_R1_OPX (WRPRS, 0, 0, 0)
+#define MASK_R1_WRPRS	MASK_R1_OPX (0, 1, 0, 1)
+#define MATCH_R1_XOR	MATCH_R1_OPX0 (XOR)
+#define MASK_R1_XOR	MASK_R1_OPX0
+#define MATCH_R1_XORHI	MATCH_R1_OP (XORHI)
+#define MASK_R1_XORHI	MASK_R1_OP
+#define MATCH_R1_XORI	MATCH_R1_OP (XORI)
+#define MASK_R1_XORI	MASK_R1_OP
+
+#endif /* _NIOS2R1_H */
+
+/*#include "nios2r2.h"*/
+
+#ifndef _NIOS2R2_H_
+#define _NIOS2R2_H_
+
+/* Fields for 32-bit R2 instructions.  */
+
+#define IW_R2_OP_LSB 0
+#define IW_R2_OP_SIZE 6
+#define IW_R2_OP_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R2_OP_SIZE))
+#define IW_R2_OP_SHIFTED_MASK (IW_R2_OP_UNSHIFTED_MASK << IW_R2_OP_LSB)
+#define GET_IW_R2_OP(W) (((W) >> IW_R2_OP_LSB) & IW_R2_OP_UNSHIFTED_MASK)
+#define SET_IW_R2_OP(V) (((V) & IW_R2_OP_UNSHIFTED_MASK) << IW_R2_OP_LSB)
+
+#define IW_L26_IMM26_LSB 6
+#define IW_L26_IMM26_SIZE 26
+#define IW_L26_IMM26_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_L26_IMM26_SIZE))
+#define IW_L26_IMM26_SHIFTED_MASK (IW_L26_IMM26_UNSHIFTED_MASK << IW_L26_IMM26_LSB)
+#define GET_IW_L26_IMM26(W) (((W) >> IW_L26_IMM26_LSB) & IW_L26_IMM26_UNSHIFTED_MASK)
+#define SET_IW_L26_IMM26(V) (((V) & IW_L26_IMM26_UNSHIFTED_MASK) << IW_L26_IMM26_LSB)
+
+#define IW_F2I16_A_LSB 6
+#define IW_F2I16_A_SIZE 5
+#define IW_F2I16_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F2I16_A_SIZE))
+#define IW_F2I16_A_SHIFTED_MASK (IW_F2I16_A_UNSHIFTED_MASK << IW_F2I16_A_LSB)
+#define GET_IW_F2I16_A(W) (((W) >> IW_F2I16_A_LSB) & IW_F2I16_A_UNSHIFTED_MASK)
+#define SET_IW_F2I16_A(V) (((V) & IW_F2I16_A_UNSHIFTED_MASK) << IW_F2I16_A_LSB)
+
+#define IW_F2I16_B_LSB 11
+#define IW_F2I16_B_SIZE 5
+#define IW_F2I16_B_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F2I16_B_SIZE))
+#define IW_F2I16_B_SHIFTED_MASK (IW_F2I16_B_UNSHIFTED_MASK << IW_F2I16_B_LSB)
+#define GET_IW_F2I16_B(W) (((W) >> IW_F2I16_B_LSB) & IW_F2I16_B_UNSHIFTED_MASK)
+#define SET_IW_F2I16_B(V) (((V) & IW_F2I16_B_UNSHIFTED_MASK) << IW_F2I16_B_LSB)
+
+#define IW_F2I16_IMM16_LSB 16
+#define IW_F2I16_IMM16_SIZE 16
+#define IW_F2I16_IMM16_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F2I16_IMM16_SIZE))
+#define IW_F2I16_IMM16_SHIFTED_MASK (IW_F2I16_IMM16_UNSHIFTED_MASK << IW_F2I16_IMM16_LSB)
+#define GET_IW_F2I16_IMM16(W) (((W) >> IW_F2I16_IMM16_LSB) & IW_F2I16_IMM16_UNSHIFTED_MASK)
+#define SET_IW_F2I16_IMM16(V) (((V) & IW_F2I16_IMM16_UNSHIFTED_MASK) << IW_F2I16_IMM16_LSB)
+
+/* Common to all three I12-group formats F2X4I12, F1X4I12, F1X4L17.  */
+#define IW_I12_X_LSB 28
+#define IW_I12_X_SIZE 4
+#define IW_I12_X_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_I12_X_SIZE))
+#define IW_I12_X_SHIFTED_MASK (IW_I12_X_UNSHIFTED_MASK << IW_I12_X_LSB)
+#define GET_IW_I12_X(W) (((W) >> IW_I12_X_LSB) & IW_I12_X_UNSHIFTED_MASK)
+#define SET_IW_I12_X(V) (((V) & IW_I12_X_UNSHIFTED_MASK) << IW_I12_X_LSB)
+
+#define IW_F2X4I12_A_LSB 6
+#define IW_F2X4I12_A_SIZE 5
+#define IW_F2X4I12_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F2X4I12_A_SIZE))
+#define IW_F2X4I12_A_SHIFTED_MASK (IW_F2X4I12_A_UNSHIFTED_MASK << IW_F2X4I12_A_LSB)
+#define GET_IW_F2X4I12_A(W) (((W) >> IW_F2X4I12_A_LSB) & IW_F2X4I12_A_UNSHIFTED_MASK)
+#define SET_IW_F2X4I12_A(V) (((V) & IW_F2X4I12_A_UNSHIFTED_MASK) << IW_F2X4I12_A_LSB)
+
+#define IW_F2X4I12_B_LSB 11
+#define IW_F2X4I12_B_SIZE 5
+#define IW_F2X4I12_B_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F2X4I12_B_SIZE))
+#define IW_F2X4I12_B_SHIFTED_MASK (IW_F2X4I12_B_UNSHIFTED_MASK << IW_F2X4I12_B_LSB)
+#define GET_IW_F2X4I12_B(W) (((W) >> IW_F2X4I12_B_LSB) & IW_F2X4I12_B_UNSHIFTED_MASK)
+#define SET_IW_F2X4I12_B(V) (((V) & IW_F2X4I12_B_UNSHIFTED_MASK) << IW_F2X4I12_B_LSB)
+
+#define IW_F2X4I12_IMM12_LSB 16
+#define IW_F2X4I12_IMM12_SIZE 12
+#define IW_F2X4I12_IMM12_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F2X4I12_IMM12_SIZE))
+#define IW_F2X4I12_IMM12_SHIFTED_MASK (IW_F2X4I12_IMM12_UNSHIFTED_MASK << IW_F2X4I12_IMM12_LSB)
+#define GET_IW_F2X4I12_IMM12(W) (((W) >> IW_F2X4I12_IMM12_LSB) & IW_F2X4I12_IMM12_UNSHIFTED_MASK)
+#define SET_IW_F2X4I12_IMM12(V) (((V) & IW_F2X4I12_IMM12_UNSHIFTED_MASK) << IW_F2X4I12_IMM12_LSB)
+
+#define IW_F1X4I12_A_LSB 6
+#define IW_F1X4I12_A_SIZE 5
+#define IW_F1X4I12_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1X4I12_A_SIZE))
+#define IW_F1X4I12_A_SHIFTED_MASK (IW_F1X4I12_A_UNSHIFTED_MASK << IW_F1X4I12_A_LSB)
+#define GET_IW_F1X4I12_A(W) (((W) >> IW_F1X4I12_A_LSB) & IW_F1X4I12_A_UNSHIFTED_MASK)
+#define SET_IW_F1X4I12_A(V) (((V) & IW_F1X4I12_A_UNSHIFTED_MASK) << IW_F1X4I12_A_LSB)
+
+#define IW_F1X4I12_X_LSB 11
+#define IW_F1X4I12_X_SIZE 5
+#define IW_F1X4I12_X_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1X4I12_X_SIZE))
+#define IW_F1X4I12_X_SHIFTED_MASK (IW_F1X4I12_X_UNSHIFTED_MASK << IW_F1X4I12_X_LSB)
+#define GET_IW_F1X4I12_X(W) (((W) >> IW_F1X4I12_X_LSB) & IW_F1X4I12_X_UNSHIFTED_MASK)
+#define SET_IW_F1X4I12_X(V) (((V) & IW_F1X4I12_X_UNSHIFTED_MASK) << IW_F1X4I12_X_LSB)
+
+#define IW_F1X4I12_IMM12_LSB 16
+#define IW_F1X4I12_IMM12_SIZE 12
+#define IW_F1X4I12_IMM12_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1X4I12_IMM12_SIZE))
+#define IW_F1X4I12_IMM12_SHIFTED_MASK (IW_F1X4I12_IMM12_UNSHIFTED_MASK << IW_F1X4I12_IMM12_LSB)
+#define GET_IW_F1X4I12_IMM12(W) (((W) >> IW_F1X4I12_IMM12_LSB) & IW_F1X4I12_IMM12_UNSHIFTED_MASK)
+#define SET_IW_F1X4I12_IMM12(V) (((V) & IW_F1X4I12_IMM12_UNSHIFTED_MASK) << IW_F1X4I12_IMM12_LSB)
+
+#define IW_F1X4L17_A_LSB 6
+#define IW_F1X4L17_A_SIZE 5
+#define IW_F1X4L17_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1X4L17_A_SIZE))
+#define IW_F1X4L17_A_SHIFTED_MASK (IW_F1X4L17_A_UNSHIFTED_MASK << IW_F1X4L17_A_LSB)
+#define GET_IW_F1X4L17_A(W) (((W) >> IW_F1X4L17_A_LSB) & IW_F1X4L17_A_UNSHIFTED_MASK)
+#define SET_IW_F1X4L17_A(V) (((V) & IW_F1X4L17_A_UNSHIFTED_MASK) << IW_F1X4L17_A_LSB)
+
+#define IW_F1X4L17_ID_LSB 11
+#define IW_F1X4L17_ID_SIZE 1
+#define IW_F1X4L17_ID_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1X4L17_ID_SIZE))
+#define IW_F1X4L17_ID_SHIFTED_MASK (IW_F1X4L17_ID_UNSHIFTED_MASK << IW_F1X4L17_ID_LSB)
+#define GET_IW_F1X4L17_ID(W) (((W) >> IW_F1X4L17_ID_LSB) & IW_F1X4L17_ID_UNSHIFTED_MASK)
+#define SET_IW_F1X4L17_ID(V) (((V) & IW_F1X4L17_ID_UNSHIFTED_MASK) << IW_F1X4L17_ID_LSB)
+
+#define IW_F1X4L17_WB_LSB 12
+#define IW_F1X4L17_WB_SIZE 1
+#define IW_F1X4L17_WB_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1X4L17_WB_SIZE))
+#define IW_F1X4L17_WB_SHIFTED_MASK (IW_F1X4L17_WB_UNSHIFTED_MASK << IW_F1X4L17_WB_LSB)
+#define GET_IW_F1X4L17_WB(W) (((W) >> IW_F1X4L17_WB_LSB) & IW_F1X4L17_WB_UNSHIFTED_MASK)
+#define SET_IW_F1X4L17_WB(V) (((V) & IW_F1X4L17_WB_UNSHIFTED_MASK) << IW_F1X4L17_WB_LSB)
+
+#define IW_F1X4L17_RS_LSB 13
+#define IW_F1X4L17_RS_SIZE 1
+#define IW_F1X4L17_RS_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1X4L17_RS_SIZE))
+#define IW_F1X4L17_RS_SHIFTED_MASK (IW_F1X4L17_RS_UNSHIFTED_MASK << IW_F1X4L17_RS_LSB)
+#define GET_IW_F1X4L17_RS(W) (((W) >> IW_F1X4L17_RS_LSB) & IW_F1X4L17_RS_UNSHIFTED_MASK)
+#define SET_IW_F1X4L17_RS(V) (((V) & IW_F1X4L17_RS_UNSHIFTED_MASK) << IW_F1X4L17_RS_LSB)
+
+#define IW_F1X4L17_PC_LSB 14
+#define IW_F1X4L17_PC_SIZE 1
+#define IW_F1X4L17_PC_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1X4L17_PC_SIZE))
+#define IW_F1X4L17_PC_SHIFTED_MASK (IW_F1X4L17_PC_UNSHIFTED_MASK << IW_F1X4L17_PC_LSB)
+#define GET_IW_F1X4L17_PC(W) (((W) >> IW_F1X4L17_PC_LSB) & IW_F1X4L17_PC_UNSHIFTED_MASK)
+#define SET_IW_F1X4L17_PC(V) (((V) & IW_F1X4L17_PC_UNSHIFTED_MASK) << IW_F1X4L17_PC_LSB)
+
+#define IW_F1X4L17_RSV_LSB 15
+#define IW_F1X4L17_RSV_SIZE 1
+#define IW_F1X4L17_RSV_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1X4L17_RSV_SIZE))
+#define IW_F1X4L17_RSV_SHIFTED_MASK (IW_F1X4L17_RSV_UNSHIFTED_MASK << IW_F1X4L17_RSV_LSB)
+#define GET_IW_F1X4L17_RSV(W) (((W) >> IW_F1X4L17_RSV_LSB) & IW_F1X4L17_RSV_UNSHIFTED_MASK)
+#define SET_IW_F1X4L17_RSV(V) (((V) & IW_F1X4L17_RSV_UNSHIFTED_MASK) << IW_F1X4L17_RSV_LSB)
+
+#define IW_F1X4L17_REGMASK_LSB 16
+#define IW_F1X4L17_REGMASK_SIZE 12
+#define IW_F1X4L17_REGMASK_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1X4L17_REGMASK_SIZE))
+#define IW_F1X4L17_REGMASK_SHIFTED_MASK (IW_F1X4L17_REGMASK_UNSHIFTED_MASK << IW_F1X4L17_REGMASK_LSB)
+#define GET_IW_F1X4L17_REGMASK(W) (((W) >> IW_F1X4L17_REGMASK_LSB) & IW_F1X4L17_REGMASK_UNSHIFTED_MASK)
+#define SET_IW_F1X4L17_REGMASK(V) (((V) & IW_F1X4L17_REGMASK_UNSHIFTED_MASK) << IW_F1X4L17_REGMASK_LSB)
+
+/* Shared by OPX-group formats F3X6L5, F2X6L10, F3X6.  */
+#define IW_OPX_X_LSB 26
+#define IW_OPX_X_SIZE 6
+#define IW_OPX_X_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_OPX_X_SIZE))
+#define IW_OPX_X_SHIFTED_MASK (IW_OPX_X_UNSHIFTED_MASK << IW_OPX_X_LSB)
+#define GET_IW_OPX_X(W) (((W) >> IW_OPX_X_LSB) & IW_OPX_X_UNSHIFTED_MASK)
+#define SET_IW_OPX_X(V) (((V) & IW_OPX_X_UNSHIFTED_MASK) << IW_OPX_X_LSB)
+
+/* F3X6L5 accessors are also used for F3X6 formats.  */
+#define IW_F3X6L5_A_LSB 6
+#define IW_F3X6L5_A_SIZE 5
+#define IW_F3X6L5_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F3X6L5_A_SIZE))
+#define IW_F3X6L5_A_SHIFTED_MASK (IW_F3X6L5_A_UNSHIFTED_MASK << IW_F3X6L5_A_LSB)
+#define GET_IW_F3X6L5_A(W) (((W) >> IW_F3X6L5_A_LSB) & IW_F3X6L5_A_UNSHIFTED_MASK)
+#define SET_IW_F3X6L5_A(V) (((V) & IW_F3X6L5_A_UNSHIFTED_MASK) << IW_F3X6L5_A_LSB)
+
+#define IW_F3X6L5_B_LSB 11
+#define IW_F3X6L5_B_SIZE 5
+#define IW_F3X6L5_B_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F3X6L5_B_SIZE))
+#define IW_F3X6L5_B_SHIFTED_MASK (IW_F3X6L5_B_UNSHIFTED_MASK << IW_F3X6L5_B_LSB)
+#define GET_IW_F3X6L5_B(W) (((W) >> IW_F3X6L5_B_LSB) & IW_F3X6L5_B_UNSHIFTED_MASK)
+#define SET_IW_F3X6L5_B(V) (((V) & IW_F3X6L5_B_UNSHIFTED_MASK) << IW_F3X6L5_B_LSB)
+
+#define IW_F3X6L5_C_LSB 16
+#define IW_F3X6L5_C_SIZE 5
+#define IW_F3X6L5_C_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F3X6L5_C_SIZE))
+#define IW_F3X6L5_C_SHIFTED_MASK (IW_F3X6L5_C_UNSHIFTED_MASK << IW_F3X6L5_C_LSB)
+#define GET_IW_F3X6L5_C(W) (((W) >> IW_F3X6L5_C_LSB) & IW_F3X6L5_C_UNSHIFTED_MASK)
+#define SET_IW_F3X6L5_C(V) (((V) & IW_F3X6L5_C_UNSHIFTED_MASK) << IW_F3X6L5_C_LSB)
+
+#define IW_F3X6L5_IMM5_LSB 21
+#define IW_F3X6L5_IMM5_SIZE 5
+#define IW_F3X6L5_IMM5_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F3X6L5_IMM5_SIZE))
+#define IW_F3X6L5_IMM5_SHIFTED_MASK (IW_F3X6L5_IMM5_UNSHIFTED_MASK << IW_F3X6L5_IMM5_LSB)
+#define GET_IW_F3X6L5_IMM5(W) (((W) >> IW_F3X6L5_IMM5_LSB) & IW_F3X6L5_IMM5_UNSHIFTED_MASK)
+#define SET_IW_F3X6L5_IMM5(V) (((V) & IW_F3X6L5_IMM5_UNSHIFTED_MASK) << IW_F3X6L5_IMM5_LSB)
+
+#define IW_F2X6L10_A_LSB 6
+#define IW_F2X6L10_A_SIZE 5
+#define IW_F2X6L10_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F2X6L10_A_SIZE))
+#define IW_F2X6L10_A_SHIFTED_MASK (IW_F2X6L10_A_UNSHIFTED_MASK << IW_F2X6L10_A_LSB)
+#define GET_IW_F2X6L10_A(W) (((W) >> IW_F2X6L10_A_LSB) & IW_F2X6L10_A_UNSHIFTED_MASK)
+#define SET_IW_F2X6L10_A(V) (((V) & IW_F2X6L10_A_UNSHIFTED_MASK) << IW_F2X6L10_A_LSB)
+
+#define IW_F2X6L10_B_LSB 11
+#define IW_F2X6L10_B_SIZE 5
+#define IW_F2X6L10_B_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F2X6L10_B_SIZE))
+#define IW_F2X6L10_B_SHIFTED_MASK (IW_F2X6L10_B_UNSHIFTED_MASK << IW_F2X6L10_B_LSB)
+#define GET_IW_F2X6L10_B(W) (((W) >> IW_F2X6L10_B_LSB) & IW_F2X6L10_B_UNSHIFTED_MASK)
+#define SET_IW_F2X6L10_B(V) (((V) & IW_F2X6L10_B_UNSHIFTED_MASK) << IW_F2X6L10_B_LSB)
+
+#define IW_F2X6L10_LSB_LSB 16
+#define IW_F2X6L10_LSB_SIZE 5
+#define IW_F2X6L10_LSB_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F2X6L10_LSB_SIZE))
+#define IW_F2X6L10_LSB_SHIFTED_MASK (IW_F2X6L10_LSB_UNSHIFTED_MASK << IW_F2X6L10_LSB_LSB)
+#define GET_IW_F2X6L10_LSB(W) (((W) >> IW_F2X6L10_LSB_LSB) & IW_F2X6L10_LSB_UNSHIFTED_MASK)
+#define SET_IW_F2X6L10_LSB(V) (((V) & IW_F2X6L10_LSB_UNSHIFTED_MASK) << IW_F2X6L10_LSB_LSB)
+
+#define IW_F2X6L10_MSB_LSB 21
+#define IW_F2X6L10_MSB_SIZE 5
+#define IW_F2X6L10_MSB_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F2X6L10_MSB_SIZE))
+#define IW_F2X6L10_MSB_SHIFTED_MASK (IW_F2X6L10_MSB_UNSHIFTED_MASK << IW_F2X6L10_MSB_LSB)
+#define GET_IW_F2X6L10_MSB(W) (((W) >> IW_F2X6L10_MSB_LSB) & IW_F2X6L10_MSB_UNSHIFTED_MASK)
+#define SET_IW_F2X6L10_MSB(V) (((V) & IW_F2X6L10_MSB_UNSHIFTED_MASK) << IW_F2X6L10_MSB_LSB)
+
+#define IW_F3X8_A_LSB 6
+#define IW_F3X8_A_SIZE 5
+#define IW_F3X8_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F3X8_A_SIZE))
+#define IW_F3X8_A_SHIFTED_MASK (IW_F3X8_A_UNSHIFTED_MASK << IW_F3X8_A_LSB)
+#define GET_IW_F3X8_A(W) (((W) >> IW_F3X8_A_LSB) & IW_F3X8_A_UNSHIFTED_MASK)
+#define SET_IW_F3X8_A(V) (((V) & IW_F3X8_A_UNSHIFTED_MASK) << IW_F3X8_A_LSB)
+
+#define IW_F3X8_B_LSB 11
+#define IW_F3X8_B_SIZE 5
+#define IW_F3X8_B_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F3X8_B_SIZE))
+#define IW_F3X8_B_SHIFTED_MASK (IW_F3X8_B_UNSHIFTED_MASK << IW_F3X8_B_LSB)
+#define GET_IW_F3X8_B(W) (((W) >> IW_F3X8_B_LSB) & IW_F3X8_B_UNSHIFTED_MASK)
+#define SET_IW_F3X8_B(V) (((V) & IW_F3X8_B_UNSHIFTED_MASK) << IW_F3X8_B_LSB)
+
+#define IW_F3X8_C_LSB 16
+#define IW_F3X8_C_SIZE 5
+#define IW_F3X8_C_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F3X8_C_SIZE))
+#define IW_F3X8_C_SHIFTED_MASK (IW_F3X8_C_UNSHIFTED_MASK << IW_F3X8_C_LSB)
+#define GET_IW_F3X8_C(W) (((W) >> IW_F3X8_C_LSB) & IW_F3X8_C_UNSHIFTED_MASK)
+#define SET_IW_F3X8_C(V) (((V) & IW_F3X8_C_UNSHIFTED_MASK) << IW_F3X8_C_LSB)
+
+#define IW_F3X8_READA_LSB 21
+#define IW_F3X8_READA_SIZE 1
+#define IW_F3X8_READA_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F3X8_READA_SIZE))
+#define IW_F3X8_READA_SHIFTED_MASK (IW_F3X8_READA_UNSHIFTED_MASK << IW_F3X8_READA_LSB)
+#define GET_IW_F3X8_READA(W) (((W) >> IW_F3X8_READA_LSB) & IW_F3X8_READA_UNSHIFTED_MASK)
+#define SET_IW_F3X8_READA(V) (((V) & IW_F3X8_READA_UNSHIFTED_MASK) << IW_F3X8_READA_LSB)
+
+#define IW_F3X8_READB_LSB 22
+#define IW_F3X8_READB_SIZE 1
+#define IW_F3X8_READB_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F3X8_READB_SIZE))
+#define IW_F3X8_READB_SHIFTED_MASK (IW_F3X8_READB_UNSHIFTED_MASK << IW_F3X8_READB_LSB)
+#define GET_IW_F3X8_READB(W) (((W) >> IW_F3X8_READB_LSB) & IW_F3X8_READB_UNSHIFTED_MASK)
+#define SET_IW_F3X8_READB(V) (((V) & IW_F3X8_READB_UNSHIFTED_MASK) << IW_F3X8_READB_LSB)
+
+#define IW_F3X8_READC_LSB 23
+#define IW_F3X8_READC_SIZE 1
+#define IW_F3X8_READC_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F3X8_READC_SIZE))
+#define IW_F3X8_READC_SHIFTED_MASK (IW_F3X8_READC_UNSHIFTED_MASK << IW_F3X8_READC_LSB)
+#define GET_IW_F3X8_READC(W) (((W) >> IW_F3X8_READC_LSB) & IW_F3X8_READC_UNSHIFTED_MASK)
+#define SET_IW_F3X8_READC(V) (((V) & IW_F3X8_READC_UNSHIFTED_MASK) << IW_F3X8_READC_LSB)
+
+#define IW_F3X8_N_LSB 24
+#define IW_F3X8_N_SIZE 8
+#define IW_F3X8_N_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F3X8_N_SIZE))
+#define IW_F3X8_N_SHIFTED_MASK (IW_F3X8_N_UNSHIFTED_MASK << IW_F3X8_N_LSB)
+#define GET_IW_F3X8_N(W) (((W) >> IW_F3X8_N_LSB) & IW_F3X8_N_UNSHIFTED_MASK)
+#define SET_IW_F3X8_N(V) (((V) & IW_F3X8_N_UNSHIFTED_MASK) << IW_F3X8_N_LSB)
+
+/* 16-bit R2 fields.  */
+
+#define IW_I10_IMM10_LSB 6
+#define IW_I10_IMM10_SIZE 10
+#define IW_I10_IMM10_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_I10_IMM10_SIZE))
+#define IW_I10_IMM10_SHIFTED_MASK (IW_I10_IMM10_UNSHIFTED_MASK << IW_I10_IMM10_LSB)
+#define GET_IW_I10_IMM10(W) (((W) >> IW_I10_IMM10_LSB) & IW_I10_IMM10_UNSHIFTED_MASK)
+#define SET_IW_I10_IMM10(V) (((V) & IW_I10_IMM10_UNSHIFTED_MASK) << IW_I10_IMM10_LSB)
+
+#define IW_T1I7_A3_LSB 6
+#define IW_T1I7_A3_SIZE 3
+#define IW_T1I7_A3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T1I7_A3_SIZE))
+#define IW_T1I7_A3_SHIFTED_MASK (IW_T1I7_A3_UNSHIFTED_MASK << IW_T1I7_A3_LSB)
+#define GET_IW_T1I7_A3(W) (((W) >> IW_T1I7_A3_LSB) & IW_T1I7_A3_UNSHIFTED_MASK)
+#define SET_IW_T1I7_A3(V) (((V) & IW_T1I7_A3_UNSHIFTED_MASK) << IW_T1I7_A3_LSB)
+
+#define IW_T1I7_IMM7_LSB 9
+#define IW_T1I7_IMM7_SIZE 7
+#define IW_T1I7_IMM7_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T1I7_IMM7_SIZE))
+#define IW_T1I7_IMM7_SHIFTED_MASK (IW_T1I7_IMM7_UNSHIFTED_MASK << IW_T1I7_IMM7_LSB)
+#define GET_IW_T1I7_IMM7(W) (((W) >> IW_T1I7_IMM7_LSB) & IW_T1I7_IMM7_UNSHIFTED_MASK)
+#define SET_IW_T1I7_IMM7(V) (((V) & IW_T1I7_IMM7_UNSHIFTED_MASK) << IW_T1I7_IMM7_LSB)
+
+#define IW_T2I4_A3_LSB 6
+#define IW_T2I4_A3_SIZE 3
+#define IW_T2I4_A3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T2I4_A3_SIZE))
+#define IW_T2I4_A3_SHIFTED_MASK (IW_T2I4_A3_UNSHIFTED_MASK << IW_T2I4_A3_LSB)
+#define GET_IW_T2I4_A3(W) (((W) >> IW_T2I4_A3_LSB) & IW_T2I4_A3_UNSHIFTED_MASK)
+#define SET_IW_T2I4_A3(V) (((V) & IW_T2I4_A3_UNSHIFTED_MASK) << IW_T2I4_A3_LSB)
+
+#define IW_T2I4_B3_LSB 9
+#define IW_T2I4_B3_SIZE 3
+#define IW_T2I4_B3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T2I4_B3_SIZE))
+#define IW_T2I4_B3_SHIFTED_MASK (IW_T2I4_B3_UNSHIFTED_MASK << IW_T2I4_B3_LSB)
+#define GET_IW_T2I4_B3(W) (((W) >> IW_T2I4_B3_LSB) & IW_T2I4_B3_UNSHIFTED_MASK)
+#define SET_IW_T2I4_B3(V) (((V) & IW_T2I4_B3_UNSHIFTED_MASK) << IW_T2I4_B3_LSB)
+
+#define IW_T2I4_IMM4_LSB 12
+#define IW_T2I4_IMM4_SIZE 4
+#define IW_T2I4_IMM4_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T2I4_IMM4_SIZE))
+#define IW_T2I4_IMM4_SHIFTED_MASK (IW_T2I4_IMM4_UNSHIFTED_MASK << IW_T2I4_IMM4_LSB)
+#define GET_IW_T2I4_IMM4(W) (((W) >> IW_T2I4_IMM4_LSB) & IW_T2I4_IMM4_UNSHIFTED_MASK)
+#define SET_IW_T2I4_IMM4(V) (((V) & IW_T2I4_IMM4_UNSHIFTED_MASK) << IW_T2I4_IMM4_LSB)
+
+#define IW_T1X1I6_A3_LSB 6
+#define IW_T1X1I6_A3_SIZE 3
+#define IW_T1X1I6_A3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T1X1I6_A3_SIZE))
+#define IW_T1X1I6_A3_SHIFTED_MASK (IW_T1X1I6_A3_UNSHIFTED_MASK << IW_T1X1I6_A3_LSB)
+#define GET_IW_T1X1I6_A3(W) (((W) >> IW_T1X1I6_A3_LSB) & IW_T1X1I6_A3_UNSHIFTED_MASK)
+#define SET_IW_T1X1I6_A3(V) (((V) & IW_T1X1I6_A3_UNSHIFTED_MASK) << IW_T1X1I6_A3_LSB)
+
+#define IW_T1X1I6_IMM6_LSB 9
+#define IW_T1X1I6_IMM6_SIZE 6
+#define IW_T1X1I6_IMM6_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T1X1I6_IMM6_SIZE))
+#define IW_T1X1I6_IMM6_SHIFTED_MASK (IW_T1X1I6_IMM6_UNSHIFTED_MASK << IW_T1X1I6_IMM6_LSB)
+#define GET_IW_T1X1I6_IMM6(W) (((W) >> IW_T1X1I6_IMM6_LSB) & IW_T1X1I6_IMM6_UNSHIFTED_MASK)
+#define SET_IW_T1X1I6_IMM6(V) (((V) & IW_T1X1I6_IMM6_UNSHIFTED_MASK) << IW_T1X1I6_IMM6_LSB)
+
+#define IW_T1X1I6_X_LSB 15
+#define IW_T1X1I6_X_SIZE 1
+#define IW_T1X1I6_X_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T1X1I6_X_SIZE))
+#define IW_T1X1I6_X_SHIFTED_MASK (IW_T1X1I6_X_UNSHIFTED_MASK << IW_T1X1I6_X_LSB)
+#define GET_IW_T1X1I6_X(W) (((W) >> IW_T1X1I6_X_LSB) & IW_T1X1I6_X_UNSHIFTED_MASK)
+#define SET_IW_T1X1I6_X(V) (((V) & IW_T1X1I6_X_UNSHIFTED_MASK) << IW_T1X1I6_X_LSB)
+
+#define IW_X1I7_IMM7_LSB 6
+#define IW_X1I7_IMM7_SIZE 7
+#define IW_X1I7_IMM7_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_X1I7_IMM7_SIZE))
+#define IW_X1I7_IMM7_SHIFTED_MASK (IW_X1I7_IMM7_UNSHIFTED_MASK << IW_X1I7_IMM7_LSB)
+#define GET_IW_X1I7_IMM7(W) (((W) >> IW_X1I7_IMM7_LSB) & IW_X1I7_IMM7_UNSHIFTED_MASK)
+#define SET_IW_X1I7_IMM7(V) (((V) & IW_X1I7_IMM7_UNSHIFTED_MASK) << IW_X1I7_IMM7_LSB)
+
+#define IW_X1I7_RSV_LSB 13
+#define IW_X1I7_RSV_SIZE 2
+#define IW_X1I7_RSV_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_X1I7_RSV_SIZE))
+#define IW_X1I7_RSV_SHIFTED_MASK (IW_X1I7_RSV_UNSHIFTED_MASK << IW_X1I7_RSV_LSB)
+#define GET_IW_X1I7_RSV(W) (((W) >> IW_X1I7_RSV_LSB) & IW_X1I7_RSV_UNSHIFTED_MASK)
+#define SET_IW_X1I7_RSV(V) (((V) & IW_X1I7_RSV_UNSHIFTED_MASK) << IW_X1I7_RSV_LSB)
+
+#define IW_X1I7_X_LSB 15
+#define IW_X1I7_X_SIZE 1
+#define IW_X1I7_X_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_X1I7_X_SIZE))
+#define IW_X1I7_X_SHIFTED_MASK (IW_X1I7_X_UNSHIFTED_MASK << IW_X1I7_X_LSB)
+#define GET_IW_X1I7_X(W) (((W) >> IW_X1I7_X_LSB) & IW_X1I7_X_UNSHIFTED_MASK)
+#define SET_IW_X1I7_X(V) (((V) & IW_X1I7_X_UNSHIFTED_MASK) << IW_X1I7_X_LSB)
+
+#define IW_L5I4X1_IMM4_LSB 6
+#define IW_L5I4X1_IMM4_SIZE 4
+#define IW_L5I4X1_IMM4_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_L5I4X1_IMM4_SIZE))
+#define IW_L5I4X1_IMM4_SHIFTED_MASK (IW_L5I4X1_IMM4_UNSHIFTED_MASK << IW_L5I4X1_IMM4_LSB)
+#define GET_IW_L5I4X1_IMM4(W) (((W) >> IW_L5I4X1_IMM4_LSB) & IW_L5I4X1_IMM4_UNSHIFTED_MASK)
+#define SET_IW_L5I4X1_IMM4(V) (((V) & IW_L5I4X1_IMM4_UNSHIFTED_MASK) << IW_L5I4X1_IMM4_LSB)
+
+#define IW_L5I4X1_REGRANGE_LSB 10
+#define IW_L5I4X1_REGRANGE_SIZE 3
+#define IW_L5I4X1_REGRANGE_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_L5I4X1_REGRANGE_SIZE))
+#define IW_L5I4X1_REGRANGE_SHIFTED_MASK (IW_L5I4X1_REGRANGE_UNSHIFTED_MASK << IW_L5I4X1_REGRANGE_LSB)
+#define GET_IW_L5I4X1_REGRANGE(W) (((W) >> IW_L5I4X1_REGRANGE_LSB) & IW_L5I4X1_REGRANGE_UNSHIFTED_MASK)
+#define SET_IW_L5I4X1_REGRANGE(V) (((V) & IW_L5I4X1_REGRANGE_UNSHIFTED_MASK) << IW_L5I4X1_REGRANGE_LSB)
+
+#define IW_L5I4X1_FP_LSB 13
+#define IW_L5I4X1_FP_SIZE 1
+#define IW_L5I4X1_FP_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_L5I4X1_FP_SIZE))
+#define IW_L5I4X1_FP_SHIFTED_MASK (IW_L5I4X1_FP_UNSHIFTED_MASK << IW_L5I4X1_FP_LSB)
+#define GET_IW_L5I4X1_FP(W) (((W) >> IW_L5I4X1_FP_LSB) & IW_L5I4X1_FP_UNSHIFTED_MASK)
+#define SET_IW_L5I4X1_FP(V) (((V) & IW_L5I4X1_FP_UNSHIFTED_MASK) << IW_L5I4X1_FP_LSB)
+
+#define IW_L5I4X1_CS_LSB 14
+#define IW_L5I4X1_CS_SIZE 1
+#define IW_L5I4X1_CS_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_L5I4X1_CS_SIZE))
+#define IW_L5I4X1_CS_SHIFTED_MASK (IW_L5I4X1_CS_UNSHIFTED_MASK << IW_L5I4X1_CS_LSB)
+#define GET_IW_L5I4X1_CS(W) (((W) >> IW_L5I4X1_CS_LSB) & IW_L5I4X1_CS_UNSHIFTED_MASK)
+#define SET_IW_L5I4X1_CS(V) (((V) & IW_L5I4X1_CS_UNSHIFTED_MASK) << IW_L5I4X1_CS_LSB)
+
+#define IW_L5I4X1_X_LSB 15
+#define IW_L5I4X1_X_SIZE 1
+#define IW_L5I4X1_X_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_L5I4X1_X_SIZE))
+#define IW_L5I4X1_X_SHIFTED_MASK (IW_L5I4X1_X_UNSHIFTED_MASK << IW_L5I4X1_X_LSB)
+#define GET_IW_L5I4X1_X(W) (((W) >> IW_L5I4X1_X_LSB) & IW_L5I4X1_X_UNSHIFTED_MASK)
+#define SET_IW_L5I4X1_X(V) (((V) & IW_L5I4X1_X_UNSHIFTED_MASK) << IW_L5I4X1_X_LSB)
+
+#define IW_T2X1L3_A3_LSB 6
+#define IW_T2X1L3_A3_SIZE 3
+#define IW_T2X1L3_A3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T2X1L3_A3_SIZE))
+#define IW_T2X1L3_A3_SHIFTED_MASK (IW_T2X1L3_A3_UNSHIFTED_MASK << IW_T2X1L3_A3_LSB)
+#define GET_IW_T2X1L3_A3(W) (((W) >> IW_T2X1L3_A3_LSB) & IW_T2X1L3_A3_UNSHIFTED_MASK)
+#define SET_IW_T2X1L3_A3(V) (((V) & IW_T2X1L3_A3_UNSHIFTED_MASK) << IW_T2X1L3_A3_LSB)
+
+#define IW_T2X1L3_B3_LSB 9
+#define IW_T2X1L3_B3_SIZE 3
+#define IW_T2X1L3_B3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T2X1L3_B3_SIZE))
+#define IW_T2X1L3_B3_SHIFTED_MASK (IW_T2X1L3_B3_UNSHIFTED_MASK << IW_T2X1L3_B3_LSB)
+#define GET_IW_T2X1L3_B3(W) (((W) >> IW_T2X1L3_B3_LSB) & IW_T2X1L3_B3_UNSHIFTED_MASK)
+#define SET_IW_T2X1L3_B3(V) (((V) & IW_T2X1L3_B3_UNSHIFTED_MASK) << IW_T2X1L3_B3_LSB)
+
+#define IW_T2X1L3_SHAMT_LSB 12
+#define IW_T2X1L3_SHAMT_SIZE 3
+#define IW_T2X1L3_SHAMT_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T2X1L3_SHAMT_SIZE))
+#define IW_T2X1L3_SHAMT_SHIFTED_MASK (IW_T2X1L3_SHAMT_UNSHIFTED_MASK << IW_T2X1L3_SHAMT_LSB)
+#define GET_IW_T2X1L3_SHAMT(W) (((W) >> IW_T2X1L3_SHAMT_LSB) & IW_T2X1L3_SHAMT_UNSHIFTED_MASK)
+#define SET_IW_T2X1L3_SHAMT(V) (((V) & IW_T2X1L3_SHAMT_UNSHIFTED_MASK) << IW_T2X1L3_SHAMT_LSB)
+
+#define IW_T2X1L3_X_LSB 15
+#define IW_T2X1L3_X_SIZE 1
+#define IW_T2X1L3_X_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T2X1L3_X_SIZE))
+#define IW_T2X1L3_X_SHIFTED_MASK (IW_T2X1L3_X_UNSHIFTED_MASK << IW_T2X1L3_X_LSB)
+#define GET_IW_T2X1L3_X(W) (((W) >> IW_T2X1L3_X_LSB) & IW_T2X1L3_X_UNSHIFTED_MASK)
+#define SET_IW_T2X1L3_X(V) (((V) & IW_T2X1L3_X_UNSHIFTED_MASK) << IW_T2X1L3_X_LSB)
+
+#define IW_T2X1I3_A3_LSB 6
+#define IW_T2X1I3_A3_SIZE 3
+#define IW_T2X1I3_A3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T2X1I3_A3_SIZE))
+#define IW_T2X1I3_A3_SHIFTED_MASK (IW_T2X1I3_A3_UNSHIFTED_MASK << IW_T2X1I3_A3_LSB)
+#define GET_IW_T2X1I3_A3(W) (((W) >> IW_T2X1I3_A3_LSB) & IW_T2X1I3_A3_UNSHIFTED_MASK)
+#define SET_IW_T2X1I3_A3(V) (((V) & IW_T2X1I3_A3_UNSHIFTED_MASK) << IW_T2X1I3_A3_LSB)
+
+#define IW_T2X1I3_B3_LSB 9
+#define IW_T2X1I3_B3_SIZE 3
+#define IW_T2X1I3_B3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T2X1I3_B3_SIZE))
+#define IW_T2X1I3_B3_SHIFTED_MASK (IW_T2X1I3_B3_UNSHIFTED_MASK << IW_T2X1I3_B3_LSB)
+#define GET_IW_T2X1I3_B3(W) (((W) >> IW_T2X1I3_B3_LSB) & IW_T2X1I3_B3_UNSHIFTED_MASK)
+#define SET_IW_T2X1I3_B3(V) (((V) & IW_T2X1I3_B3_UNSHIFTED_MASK) << IW_T2X1I3_B3_LSB)
+
+#define IW_T2X1I3_IMM3_LSB 12
+#define IW_T2X1I3_IMM3_SIZE 3
+#define IW_T2X1I3_IMM3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T2X1I3_IMM3_SIZE))
+#define IW_T2X1I3_IMM3_SHIFTED_MASK (IW_T2X1I3_IMM3_UNSHIFTED_MASK << IW_T2X1I3_IMM3_LSB)
+#define GET_IW_T2X1I3_IMM3(W) (((W) >> IW_T2X1I3_IMM3_LSB) & IW_T2X1I3_IMM3_UNSHIFTED_MASK)
+#define SET_IW_T2X1I3_IMM3(V) (((V) & IW_T2X1I3_IMM3_UNSHIFTED_MASK) << IW_T2X1I3_IMM3_LSB)
+
+#define IW_T2X1I3_X_LSB 15
+#define IW_T2X1I3_X_SIZE 1
+#define IW_T2X1I3_X_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T2X1I3_X_SIZE))
+#define IW_T2X1I3_X_SHIFTED_MASK (IW_T2X1I3_X_UNSHIFTED_MASK << IW_T2X1I3_X_LSB)
+#define GET_IW_T2X1I3_X(W) (((W) >> IW_T2X1I3_X_LSB) & IW_T2X1I3_X_UNSHIFTED_MASK)
+#define SET_IW_T2X1I3_X(V) (((V) & IW_T2X1I3_X_UNSHIFTED_MASK) << IW_T2X1I3_X_LSB)
+
+#define IW_T3X1_A3_LSB 6
+#define IW_T3X1_A3_SIZE 3
+#define IW_T3X1_A3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T3X1_A3_SIZE))
+#define IW_T3X1_A3_SHIFTED_MASK (IW_T3X1_A3_UNSHIFTED_MASK << IW_T3X1_A3_LSB)
+#define GET_IW_T3X1_A3(W) (((W) >> IW_T3X1_A3_LSB) & IW_T3X1_A3_UNSHIFTED_MASK)
+#define SET_IW_T3X1_A3(V) (((V) & IW_T3X1_A3_UNSHIFTED_MASK) << IW_T3X1_A3_LSB)
+
+#define IW_T3X1_B3_LSB 9
+#define IW_T3X1_B3_SIZE 3
+#define IW_T3X1_B3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T3X1_B3_SIZE))
+#define IW_T3X1_B3_SHIFTED_MASK (IW_T3X1_B3_UNSHIFTED_MASK << IW_T3X1_B3_LSB)
+#define GET_IW_T3X1_B3(W) (((W) >> IW_T3X1_B3_LSB) & IW_T3X1_B3_UNSHIFTED_MASK)
+#define SET_IW_T3X1_B3(V) (((V) & IW_T3X1_B3_UNSHIFTED_MASK) << IW_T3X1_B3_LSB)
+
+#define IW_T3X1_C3_LSB 12
+#define IW_T3X1_C3_SIZE 3
+#define IW_T3X1_C3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T3X1_C3_SIZE))
+#define IW_T3X1_C3_SHIFTED_MASK (IW_T3X1_C3_UNSHIFTED_MASK << IW_T3X1_C3_LSB)
+#define GET_IW_T3X1_C3(W) (((W) >> IW_T3X1_C3_LSB) & IW_T3X1_C3_UNSHIFTED_MASK)
+#define SET_IW_T3X1_C3(V) (((V) & IW_T3X1_C3_UNSHIFTED_MASK) << IW_T3X1_C3_LSB)
+
+#define IW_T3X1_X_LSB 15
+#define IW_T3X1_X_SIZE 1
+#define IW_T3X1_X_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T3X1_X_SIZE))
+#define IW_T3X1_X_SHIFTED_MASK (IW_T3X1_X_UNSHIFTED_MASK << IW_T3X1_X_LSB)
+#define GET_IW_T3X1_X(W) (((W) >> IW_T3X1_X_LSB) & IW_T3X1_X_UNSHIFTED_MASK)
+#define SET_IW_T3X1_X(V) (((V) & IW_T3X1_X_UNSHIFTED_MASK) << IW_T3X1_X_LSB)
+
+/* The X field for all three R.N-class instruction formats is represented
+   here as 4 bits, including the bits defined as constant 0 or 1 that
+   determine which of the formats T2X3, F1X1, or X2L5 it is.  */
+#define IW_R_N_X_LSB 12
+#define IW_R_N_X_SIZE 4
+#define IW_R_N_X_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R_N_X_SIZE))
+#define IW_R_N_X_SHIFTED_MASK (IW_R_N_X_UNSHIFTED_MASK << IW_R_N_X_LSB)
+#define GET_IW_R_N_X(W) (((W) >> IW_R_N_X_LSB) & IW_R_N_X_UNSHIFTED_MASK)
+#define SET_IW_R_N_X(V) (((V) & IW_R_N_X_UNSHIFTED_MASK) << IW_R_N_X_LSB)
+
+#define IW_T2X3_A3_LSB 6
+#define IW_T2X3_A3_SIZE 3
+#define IW_T2X3_A3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T2X3_A3_SIZE))
+#define IW_T2X3_A3_SHIFTED_MASK (IW_T2X3_A3_UNSHIFTED_MASK << IW_T2X3_A3_LSB)
+#define GET_IW_T2X3_A3(W) (((W) >> IW_T2X3_A3_LSB) & IW_T2X3_A3_UNSHIFTED_MASK)
+#define SET_IW_T2X3_A3(V) (((V) & IW_T2X3_A3_UNSHIFTED_MASK) << IW_T2X3_A3_LSB)
+
+#define IW_T2X3_B3_LSB 9
+#define IW_T2X3_B3_SIZE 3
+#define IW_T2X3_B3_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_T2X3_B3_SIZE))
+#define IW_T2X3_B3_SHIFTED_MASK (IW_T2X3_B3_UNSHIFTED_MASK << IW_T2X3_B3_LSB)
+#define GET_IW_T2X3_B3(W) (((W) >> IW_T2X3_B3_LSB) & IW_T2X3_B3_UNSHIFTED_MASK)
+#define SET_IW_T2X3_B3(V) (((V) & IW_T2X3_B3_UNSHIFTED_MASK) << IW_T2X3_B3_LSB)
+
+#define IW_F1X1_A_LSB 6
+#define IW_F1X1_A_SIZE 5
+#define IW_F1X1_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1X1_A_SIZE))
+#define IW_F1X1_A_SHIFTED_MASK (IW_F1X1_A_UNSHIFTED_MASK << IW_F1X1_A_LSB)
+#define GET_IW_F1X1_A(W) (((W) >> IW_F1X1_A_LSB) & IW_F1X1_A_UNSHIFTED_MASK)
+#define SET_IW_F1X1_A(V) (((V) & IW_F1X1_A_UNSHIFTED_MASK) << IW_F1X1_A_LSB)
+
+#define IW_F1X1_RSV_LSB 11
+#define IW_F1X1_RSV_SIZE 1
+#define IW_F1X1_RSV_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1X1_RSV_SIZE))
+#define IW_F1X1_RSV_SHIFTED_MASK (IW_F1X1_RSV_UNSHIFTED_MASK << IW_F1X1_RSV_LSB)
+#define GET_IW_F1X1_RSV(W) (((W) >> IW_F1X1_RSV_LSB) & IW_F1X1_RSV_UNSHIFTED_MASK)
+#define SET_IW_F1X1_RSV(V) (((V) & IW_F1X1_RSV_UNSHIFTED_MASK) << IW_F1X1_RSV_LSB)
+
+#define IW_X2L5_IMM5_LSB 6
+#define IW_X2L5_IMM5_SIZE 5
+#define IW_X2L5_IMM5_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_X2L5_IMM5_SIZE))
+#define IW_X2L5_IMM5_SHIFTED_MASK (IW_X2L5_IMM5_UNSHIFTED_MASK << IW_X2L5_IMM5_LSB)
+#define GET_IW_X2L5_IMM5(W) (((W) >> IW_X2L5_IMM5_LSB) & IW_X2L5_IMM5_UNSHIFTED_MASK)
+#define SET_IW_X2L5_IMM5(V) (((V) & IW_X2L5_IMM5_UNSHIFTED_MASK) << IW_X2L5_IMM5_LSB)
+
+#define IW_X2L5_RSV_LSB 11
+#define IW_X2L5_RSV_SIZE 1
+#define IW_X2L5_RSV_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_X2L5_RSV_SIZE))
+#define IW_X2L5_RSV_SHIFTED_MASK (IW_X2L5_RSV_UNSHIFTED_MASK << IW_X2L5_RSV_LSB)
+#define GET_IW_X2L5_RSV(W) (((W) >> IW_X2L5_RSV_LSB) & IW_X2L5_RSV_UNSHIFTED_MASK)
+#define SET_IW_X2L5_RSV(V) (((V) & IW_X2L5_RSV_UNSHIFTED_MASK) << IW_X2L5_RSV_LSB)
+
+#define IW_F1I5_IMM5_LSB 6
+#define IW_F1I5_IMM5_SIZE 5
+#define IW_F1I5_IMM5_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1I5_IMM5_SIZE))
+#define IW_F1I5_IMM5_SHIFTED_MASK (IW_F1I5_IMM5_UNSHIFTED_MASK << IW_F1I5_IMM5_LSB)
+#define GET_IW_F1I5_IMM5(W) (((W) >> IW_F1I5_IMM5_LSB) & IW_F1I5_IMM5_UNSHIFTED_MASK)
+#define SET_IW_F1I5_IMM5(V) (((V) & IW_F1I5_IMM5_UNSHIFTED_MASK) << IW_F1I5_IMM5_LSB)
+
+#define IW_F1I5_B_LSB 11
+#define IW_F1I5_B_SIZE 5
+#define IW_F1I5_B_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F1I5_B_SIZE))
+#define IW_F1I5_B_SHIFTED_MASK (IW_F1I5_B_UNSHIFTED_MASK << IW_F1I5_B_LSB)
+#define GET_IW_F1I5_B(W) (((W) >> IW_F1I5_B_LSB) & IW_F1I5_B_UNSHIFTED_MASK)
+#define SET_IW_F1I5_B(V) (((V) & IW_F1I5_B_UNSHIFTED_MASK) << IW_F1I5_B_LSB)
+
+#define IW_F2_A_LSB 6
+#define IW_F2_A_SIZE 5
+#define IW_F2_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F2_A_SIZE))
+#define IW_F2_A_SHIFTED_MASK (IW_F2_A_UNSHIFTED_MASK << IW_F2_A_LSB)
+#define GET_IW_F2_A(W) (((W) >> IW_F2_A_LSB) & IW_F2_A_UNSHIFTED_MASK)
+#define SET_IW_F2_A(V) (((V) & IW_F2_A_UNSHIFTED_MASK) << IW_F2_A_LSB)
+
+#define IW_F2_B_LSB 11
+#define IW_F2_B_SIZE 5
+#define IW_F2_B_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_F2_B_SIZE))
+#define IW_F2_B_SHIFTED_MASK (IW_F2_B_UNSHIFTED_MASK << IW_F2_B_LSB)
+#define GET_IW_F2_B(W) (((W) >> IW_F2_B_LSB) & IW_F2_B_UNSHIFTED_MASK)
+#define SET_IW_F2_B(V) (((V) & IW_F2_B_UNSHIFTED_MASK) << IW_F2_B_LSB)
+
+/* R2 opcodes.  */
+#define R2_OP_CALL 0
+#define R2_OP_AS_N 1
+#define R2_OP_BR 2
+#define R2_OP_BR_N 3
+#define R2_OP_ADDI 4
+#define R2_OP_LDBU_N 5
+#define R2_OP_LDBU 6
+#define R2_OP_LDB 7
+#define R2_OP_JMPI 8
+#define R2_OP_R_N 9
+#define R2_OP_ANDI_N 11
+#define R2_OP_ANDI 12
+#define R2_OP_LDHU_N 13
+#define R2_OP_LDHU 14
+#define R2_OP_LDH 15
+#define R2_OP_ASI_N 17
+#define R2_OP_BGE 18
+#define R2_OP_LDWSP_N 19
+#define R2_OP_ORI 20
+#define R2_OP_LDW_N 21
+#define R2_OP_CMPGEI 22
+#define R2_OP_LDW 23
+#define R2_OP_SHI_N 25
+#define R2_OP_BLT 26
+#define R2_OP_MOVI_N 27
+#define R2_OP_XORI 28
+#define R2_OP_STZ_N 29
+#define R2_OP_CMPLTI 30
+#define R2_OP_ANDCI 31
+#define R2_OP_OPX 32
+#define R2_OP_PP_N 33
+#define R2_OP_BNE 34
+#define R2_OP_BNEZ_N 35
+#define R2_OP_MULI 36
+#define R2_OP_STB_N 37
+#define R2_OP_CMPNEI 38
+#define R2_OP_STB 39
+#define R2_OP_I12 40
+#define R2_OP_SPI_N 41
+#define R2_OP_BEQ 42
+#define R2_OP_BEQZ_N 43
+#define R2_OP_ANDHI 44
+#define R2_OP_STH_N 45
+#define R2_OP_CMPEQI 46
+#define R2_OP_STH 47
+#define R2_OP_CUSTOM 48
+#define R2_OP_BGEU 50
+#define R2_OP_STWSP_N 51
+#define R2_OP_ORHI 52
+#define R2_OP_STW_N 53
+#define R2_OP_CMPGEUI 54
+#define R2_OP_STW 55
+#define R2_OP_BLTU 58
+#define R2_OP_MOV_N 59
+#define R2_OP_XORHI 60
+#define R2_OP_SPADDI_N 61
+#define R2_OP_CMPLTUI 62
+#define R2_OP_ANDCHI 63
+
+#define R2_OPX_WRPIE 0
+#define R2_OPX_ERET 1
+#define R2_OPX_ROLI 2
+#define R2_OPX_ROL 3
+#define R2_OPX_FLUSHP 4
+#define R2_OPX_RET 5
+#define R2_OPX_NOR 6
+#define R2_OPX_MULXUU 7
+#define R2_OPX_ENI 8
+#define R2_OPX_BRET 9
+#define R2_OPX_ROR 11
+#define R2_OPX_FLUSHI 12
+#define R2_OPX_JMP 13
+#define R2_OPX_AND 14
+#define R2_OPX_CMPGE 16
+#define R2_OPX_SLLI 18
+#define R2_OPX_SLL 19
+#define R2_OPX_WRPRS 20
+#define R2_OPX_OR 22
+#define R2_OPX_MULXSU 23
+#define R2_OPX_CMPLT 24
+#define R2_OPX_SRLI 26
+#define R2_OPX_SRL 27
+#define R2_OPX_NEXTPC 28
+#define R2_OPX_CALLR 29
+#define R2_OPX_XOR 30
+#define R2_OPX_MULXSS 31
+#define R2_OPX_CMPNE 32
+#define R2_OPX_INSERT 35
+#define R2_OPX_DIVU 36
+#define R2_OPX_DIV 37
+#define R2_OPX_RDCTL 38
+#define R2_OPX_MUL 39
+#define R2_OPX_CMPEQ 40
+#define R2_OPX_INITI 41
+#define R2_OPX_MERGE 43
+#define R2_OPX_HBREAK 44
+#define R2_OPX_TRAP 45
+#define R2_OPX_WRCTL 46
+#define R2_OPX_CMPGEU 48
+#define R2_OPX_ADD 49
+#define R2_OPX_EXTRACT 51
+#define R2_OPX_BREAK 52
+#define R2_OPX_LDEX 53
+#define R2_OPX_SYNC 54
+#define R2_OPX_LDSEX 55
+#define R2_OPX_CMPLTU 56
+#define R2_OPX_SUB 57
+#define R2_OPX_SRAI 58
+#define R2_OPX_SRA 59
+#define R2_OPX_STEX 61
+#define R2_OPX_STSEX 63
+
+#define R2_I12_LDBIO 0
+#define R2_I12_STBIO 1
+#define R2_I12_LDBUIO 2
+#define R2_I12_DCACHE 3
+#define R2_I12_LDHIO 4
+#define R2_I12_STHIO 5
+#define R2_I12_LDHUIO 6
+#define R2_I12_RDPRS 7
+#define R2_I12_LDWIO 8
+#define R2_I12_STWIO 9
+#define R2_I12_LDWM 12
+#define R2_I12_STWM 13
+
+#define R2_DCACHE_INITD 0
+#define R2_DCACHE_INITDA 1
+#define R2_DCACHE_FLUSHD 2
+#define R2_DCACHE_FLUSHDA 3
+
+#define R2_AS_N_ADD_N 0
+#define R2_AS_N_SUB_N 1
+
+#define R2_R_N_AND_N 0
+#define R2_R_N_OR_N 2
+#define R2_R_N_XOR_N 3
+#define R2_R_N_SLL_N 4
+#define R2_R_N_SRL_N 5
+#define R2_R_N_NOT_N 6
+#define R2_R_N_NEG_N 7
+#define R2_R_N_CALLR_N 8
+#define R2_R_N_JMPR_N 10
+#define R2_R_N_BREAK_N 12
+#define R2_R_N_TRAP_N 13
+#define R2_R_N_RET_N 14
+
+#define R2_SPI_N_SPINCI_N 0
+#define R2_SPI_N_SPDECI_N 1
+
+#define R2_ASI_N_ADDI_N 0
+#define R2_ASI_N_SUBI_N 1
+
+#define R2_SHI_N_SLLI_N 0
+#define R2_SHI_N_SRLI_N 1
+
+#define R2_PP_N_POP_N 0
+#define R2_PP_N_PUSH_N 1
+
+#define R2_STZ_N_STWZ_N 0
+#define R2_STZ_N_STBZ_N 1
+
+/* Convenience macros for R2 encodings. */
+
+#define MATCH_R2_OP(NAME) \
+  (SET_IW_R2_OP (R2_OP_##NAME))
+#define MASK_R2_OP \
+  IW_R2_OP_SHIFTED_MASK
+
+#define MATCH_R2_OPX0(NAME) \
+  (SET_IW_R2_OP (R2_OP_OPX) | SET_IW_OPX_X (R2_OPX_##NAME))
+#define MASK_R2_OPX0 \
+  (IW_R2_OP_SHIFTED_MASK | IW_OPX_X_SHIFTED_MASK \
+   | IW_F3X6L5_IMM5_SHIFTED_MASK)
+
+#define MATCH_R2_OPX(NAME, A, B, C)				\
+  (MATCH_R2_OPX0 (NAME) | SET_IW_F3X6L5_A (A) | SET_IW_F3X6L5_B (B) \
+   | SET_IW_F3X6L5_C (C))
+#define MASK_R2_OPX(A, B, C, N)				\
+  (IW_R2_OP_SHIFTED_MASK | IW_OPX_X_SHIFTED_MASK	\
+   | (A ? IW_F3X6L5_A_SHIFTED_MASK : 0)			\
+   | (B ? IW_F3X6L5_B_SHIFTED_MASK : 0)			\
+   | (C ? IW_F3X6L5_C_SHIFTED_MASK : 0)			\
+   | (N ? IW_F3X6L5_IMM5_SHIFTED_MASK : 0))
+
+#define MATCH_R2_I12(NAME) \
+  (SET_IW_R2_OP (R2_OP_I12) | SET_IW_I12_X (R2_I12_##NAME))
+#define MASK_R2_I12 \
+  (IW_R2_OP_SHIFTED_MASK | IW_I12_X_SHIFTED_MASK )
+
+#define MATCH_R2_DCACHE(NAME) \
+  (MATCH_R2_I12(DCACHE) | SET_IW_F1X4I12_X (R2_DCACHE_##NAME))
+#define MASK_R2_DCACHE \
+  (MASK_R2_I12 | IW_F1X4I12_X_SHIFTED_MASK)
+
+#define MATCH_R2_R_N(NAME) \
+  (SET_IW_R2_OP (R2_OP_R_N) | SET_IW_R_N_X (R2_R_N_##NAME))
+#define MASK_R2_R_N \
+  (IW_R2_OP_SHIFTED_MASK | IW_R_N_X_SHIFTED_MASK )
+
+/* Match/mask macros for R2 instructions.  */
+
+#define MATCH_R2_ADD	MATCH_R2_OPX0 (ADD)
+#define MASK_R2_ADD	MASK_R2_OPX0
+#define MATCH_R2_ADDI	MATCH_R2_OP (ADDI)
+#define MASK_R2_ADDI	MASK_R2_OP
+#define MATCH_R2_ADD_N	(MATCH_R2_OP (AS_N) | SET_IW_T3X1_X (R2_AS_N_ADD_N))
+#define MASK_R2_ADD_N	(MASK_R2_OP | IW_T3X1_X_SHIFTED_MASK)
+#define MATCH_R2_ADDI_N	(MATCH_R2_OP (ASI_N) | SET_IW_T2X1I3_X (R2_ASI_N_ADDI_N))
+#define MASK_R2_ADDI_N	(MASK_R2_OP | IW_T2X1I3_X_SHIFTED_MASK)
+#define MATCH_R2_AND	MATCH_R2_OPX0 (AND)
+#define MASK_R2_AND	MASK_R2_OPX0
+#define MATCH_R2_ANDCHI	MATCH_R2_OP (ANDCHI)
+#define MASK_R2_ANDCHI	MASK_R2_OP
+#define MATCH_R2_ANDCI	MATCH_R2_OP (ANDCI)
+#define MASK_R2_ANDCI	MASK_R2_OP
+#define MATCH_R2_ANDHI	MATCH_R2_OP (ANDHI)
+#define MASK_R2_ANDHI	MASK_R2_OP
+#define MATCH_R2_ANDI	MATCH_R2_OP (ANDI)
+#define MASK_R2_ANDI	MASK_R2_OP
+#define MATCH_R2_ANDI_N	MATCH_R2_OP (ANDI_N)
+#define MASK_R2_ANDI_N	MASK_R2_OP
+#define MATCH_R2_AND_N	MATCH_R2_R_N (AND_N)
+#define MASK_R2_AND_N	MASK_R2_R_N
+#define MATCH_R2_BEQ	MATCH_R2_OP (BEQ)
+#define MASK_R2_BEQ	MASK_R2_OP
+#define MATCH_R2_BEQZ_N	MATCH_R2_OP (BEQZ_N)
+#define MASK_R2_BEQZ_N	MASK_R2_OP
+#define MATCH_R2_BGE	MATCH_R2_OP (BGE)
+#define MASK_R2_BGE	MASK_R2_OP
+#define MATCH_R2_BGEU	MATCH_R2_OP (BGEU)
+#define MASK_R2_BGEU	MASK_R2_OP
+#define MATCH_R2_BGT	MATCH_R2_OP (BLT)
+#define MASK_R2_BGT	MASK_R2_OP
+#define MATCH_R2_BGTU	MATCH_R2_OP (BLTU)
+#define MASK_R2_BGTU	MASK_R2_OP
+#define MATCH_R2_BLE	MATCH_R2_OP (BGE)
+#define MASK_R2_BLE	MASK_R2_OP
+#define MATCH_R2_BLEU	MATCH_R2_OP (BGEU)
+#define MASK_R2_BLEU	MASK_R2_OP
+#define MATCH_R2_BLT	MATCH_R2_OP (BLT)
+#define MASK_R2_BLT	MASK_R2_OP
+#define MATCH_R2_BLTU	MATCH_R2_OP (BLTU)
+#define MASK_R2_BLTU	MASK_R2_OP
+#define MATCH_R2_BNE	MATCH_R2_OP (BNE)
+#define MASK_R2_BNE	MASK_R2_OP
+#define MATCH_R2_BNEZ_N	MATCH_R2_OP (BNEZ_N)
+#define MASK_R2_BNEZ_N	MASK_R2_OP
+#define MATCH_R2_BR	MATCH_R2_OP (BR)
+#define MASK_R2_BR	MASK_R2_OP | IW_F2I16_A_SHIFTED_MASK | IW_F2I16_B_SHIFTED_MASK
+#define MATCH_R2_BREAK	MATCH_R2_OPX (BREAK, 0, 0, 0x1e)
+#define MASK_R2_BREAK	MASK_R2_OPX (1, 1, 1, 0)
+#define MATCH_R2_BREAK_N	MATCH_R2_R_N (BREAK_N)
+#define MASK_R2_BREAK_N	MASK_R2_R_N
+#define MATCH_R2_BRET	MATCH_R2_OPX (BRET, 0x1e, 0, 0)
+#define MASK_R2_BRET	MASK_R2_OPX (1, 1, 1, 1)
+#define MATCH_R2_BR_N	MATCH_R2_OP (BR_N)
+#define MASK_R2_BR_N	MASK_R2_OP
+#define MATCH_R2_CALL	MATCH_R2_OP (CALL)
+#define MASK_R2_CALL	MASK_R2_OP
+#define MATCH_R2_CALLR	MATCH_R2_OPX (CALLR, 0, 0, 0x1f)
+#define MASK_R2_CALLR	MASK_R2_OPX (0, 1, 1, 1)
+#define MATCH_R2_CALLR_N	MATCH_R2_R_N (CALLR_N)
+#define MASK_R2_CALLR_N	MASK_R2_R_N
+#define MATCH_R2_CMPEQ	MATCH_R2_OPX0 (CMPEQ)
+#define MASK_R2_CMPEQ	MASK_R2_OPX0
+#define MATCH_R2_CMPEQI	MATCH_R2_OP (CMPEQI)
+#define MASK_R2_CMPEQI	MASK_R2_OP
+#define MATCH_R2_CMPGE	MATCH_R2_OPX0 (CMPGE)
+#define MASK_R2_CMPGE	MASK_R2_OPX0
+#define MATCH_R2_CMPGEI	MATCH_R2_OP (CMPGEI)
+#define MASK_R2_CMPGEI	MASK_R2_OP
+#define MATCH_R2_CMPGEU	MATCH_R2_OPX0 (CMPGEU)
+#define MASK_R2_CMPGEU	MASK_R2_OPX0
+#define MATCH_R2_CMPGEUI	MATCH_R2_OP (CMPGEUI)
+#define MASK_R2_CMPGEUI	MASK_R2_OP
+#define MATCH_R2_CMPGT	MATCH_R2_OPX0 (CMPLT)
+#define MASK_R2_CMPGT	MASK_R2_OPX0
+#define MATCH_R2_CMPGTI	MATCH_R2_OP (CMPGEI)
+#define MASK_R2_CMPGTI	MASK_R2_OP
+#define MATCH_R2_CMPGTU	MATCH_R2_OPX0 (CMPLTU)
+#define MASK_R2_CMPGTU	MASK_R2_OPX0
+#define MATCH_R2_CMPGTUI	MATCH_R2_OP (CMPGEUI)
+#define MASK_R2_CMPGTUI	MASK_R2_OP
+#define MATCH_R2_CMPLE	MATCH_R2_OPX0 (CMPGE)
+#define MASK_R2_CMPLE	MASK_R2_OPX0
+#define MATCH_R2_CMPLEI	MATCH_R2_OP (CMPLTI)
+#define MASK_R2_CMPLEI	MASK_R2_OP
+#define MATCH_R2_CMPLEU	MATCH_R2_OPX0 (CMPGEU)
+#define MASK_R2_CMPLEU	MASK_R2_OPX0
+#define MATCH_R2_CMPLEUI	MATCH_R2_OP (CMPLTUI)
+#define MASK_R2_CMPLEUI	MASK_R2_OP
+#define MATCH_R2_CMPLT	MATCH_R2_OPX0 (CMPLT)
+#define MASK_R2_CMPLT	MASK_R2_OPX0
+#define MATCH_R2_CMPLTI	MATCH_R2_OP (CMPLTI)
+#define MASK_R2_CMPLTI	MASK_R2_OP
+#define MATCH_R2_CMPLTU	MATCH_R2_OPX0 (CMPLTU)
+#define MASK_R2_CMPLTU	MASK_R2_OPX0
+#define MATCH_R2_CMPLTUI	MATCH_R2_OP (CMPLTUI)
+#define MASK_R2_CMPLTUI	MASK_R2_OP
+#define MATCH_R2_CMPNE	MATCH_R2_OPX0 (CMPNE)
+#define MASK_R2_CMPNE	MASK_R2_OPX0
+#define MATCH_R2_CMPNEI	MATCH_R2_OP (CMPNEI)
+#define MASK_R2_CMPNEI	MASK_R2_OP
+#define MATCH_R2_CUSTOM	MATCH_R2_OP (CUSTOM)
+#define MASK_R2_CUSTOM	MASK_R2_OP
+#define MATCH_R2_DIV	MATCH_R2_OPX0 (DIV)
+#define MASK_R2_DIV	MASK_R2_OPX0
+#define MATCH_R2_DIVU	MATCH_R2_OPX0 (DIVU)
+#define MASK_R2_DIVU	MASK_R2_OPX0
+#define MATCH_R2_ENI	MATCH_R2_OPX (ENI, 0, 0, 0)
+#define MASK_R2_ENI	MASK_R2_OPX (1, 1, 1, 0)
+#define MATCH_R2_ERET	MATCH_R2_OPX (ERET, 0x1d, 0x1e, 0)
+#define MASK_R2_ERET	MASK_R2_OPX (1, 1, 1, 1)
+#define MATCH_R2_EXTRACT	MATCH_R2_OPX (EXTRACT, 0, 0, 0)
+#define MASK_R2_EXTRACT	MASK_R2_OPX (0, 0, 0, 0)
+#define MATCH_R2_FLUSHD	MATCH_R2_DCACHE (FLUSHD)
+#define MASK_R2_FLUSHD	MASK_R2_DCACHE
+#define MATCH_R2_FLUSHDA	MATCH_R2_DCACHE (FLUSHDA)
+#define MASK_R2_FLUSHDA	MASK_R2_DCACHE
+#define MATCH_R2_FLUSHI	MATCH_R2_OPX (FLUSHI, 0, 0, 0)
+#define MASK_R2_FLUSHI	MASK_R2_OPX (0, 1, 1, 1)
+#define MATCH_R2_FLUSHP	MATCH_R2_OPX (FLUSHP, 0, 0, 0)
+#define MASK_R2_FLUSHP	MASK_R2_OPX (1, 1, 1, 1)
+#define MATCH_R2_INITD	MATCH_R2_DCACHE (INITD)
+#define MASK_R2_INITD	MASK_R2_DCACHE
+#define MATCH_R2_INITDA	MATCH_R2_DCACHE (INITDA)
+#define MASK_R2_INITDA	MASK_R2_DCACHE
+#define MATCH_R2_INITI	MATCH_R2_OPX (INITI, 0, 0, 0)
+#define MASK_R2_INITI	MASK_R2_OPX (0, 1, 1, 1)
+#define MATCH_R2_INSERT	MATCH_R2_OPX (INSERT, 0, 0, 0)
+#define MASK_R2_INSERT	MASK_R2_OPX (0, 0, 0, 0)
+#define MATCH_R2_JMP	MATCH_R2_OPX (JMP, 0, 0, 0)
+#define MASK_R2_JMP	MASK_R2_OPX (0, 1, 1, 1)
+#define MATCH_R2_JMPI	MATCH_R2_OP (JMPI)
+#define MASK_R2_JMPI	MASK_R2_OP
+#define MATCH_R2_JMPR_N	MATCH_R2_R_N (JMPR_N)
+#define MASK_R2_JMPR_N	MASK_R2_R_N
+#define MATCH_R2_LDB	MATCH_R2_OP (LDB)
+#define MASK_R2_LDB	MASK_R2_OP
+#define MATCH_R2_LDBIO	MATCH_R2_I12 (LDBIO)
+#define MASK_R2_LDBIO	MASK_R2_I12
+#define MATCH_R2_LDBU	MATCH_R2_OP (LDBU)
+#define MASK_R2_LDBU	MASK_R2_OP
+#define MATCH_R2_LDBUIO	MATCH_R2_I12 (LDBUIO)
+#define MASK_R2_LDBUIO	MASK_R2_I12
+#define MATCH_R2_LDBU_N	MATCH_R2_OP (LDBU_N)
+#define MASK_R2_LDBU_N	MASK_R2_OP
+#define MATCH_R2_LDEX	MATCH_R2_OPX (LDEX, 0, 0, 0)
+#define MASK_R2_LDEX	MASK_R2_OPX (0, 1, 0, 1)
+#define MATCH_R2_LDH	MATCH_R2_OP (LDH)
+#define MASK_R2_LDH	MASK_R2_OP
+#define MATCH_R2_LDHIO	MATCH_R2_I12 (LDHIO)
+#define MASK_R2_LDHIO	MASK_R2_I12
+#define MATCH_R2_LDHU	MATCH_R2_OP (LDHU)
+#define MASK_R2_LDHU	MASK_R2_OP
+#define MATCH_R2_LDHUIO	MATCH_R2_I12 (LDHUIO)
+#define MASK_R2_LDHUIO	MASK_R2_I12
+#define MATCH_R2_LDHU_N	MATCH_R2_OP (LDHU_N)
+#define MASK_R2_LDHU_N	MASK_R2_OP
+#define MATCH_R2_LDSEX	MATCH_R2_OPX (LDSEX, 0, 0, 0)
+#define MASK_R2_LDSEX	MASK_R2_OPX (0, 1, 0, 1)
+#define MATCH_R2_LDW	MATCH_R2_OP (LDW)
+#define MASK_R2_LDW	MASK_R2_OP
+#define MATCH_R2_LDWIO	MATCH_R2_I12 (LDWIO)
+#define MASK_R2_LDWIO	MASK_R2_I12
+#define MATCH_R2_LDWM	MATCH_R2_I12 (LDWM)
+#define MASK_R2_LDWM	MASK_R2_I12
+#define MATCH_R2_LDWSP_N	MATCH_R2_OP (LDWSP_N)
+#define MASK_R2_LDWSP_N	MASK_R2_OP
+#define MATCH_R2_LDW_N	MATCH_R2_OP (LDW_N)
+#define MASK_R2_LDW_N	MASK_R2_OP
+#define MATCH_R2_MERGE	MATCH_R2_OPX (MERGE, 0, 0, 0)
+#define MASK_R2_MERGE	MASK_R2_OPX (0, 0, 0, 0)
+#define MATCH_R2_MOV	MATCH_R2_OPX (ADD, 0, 0, 0)
+#define MASK_R2_MOV	MASK_R2_OPX (0, 1, 0, 1)
+#define MATCH_R2_MOVHI	MATCH_R2_OP (ORHI) | SET_IW_F2I16_A (0)
+#define MASK_R2_MOVHI	MASK_R2_OP | IW_F2I16_A_SHIFTED_MASK
+#define MATCH_R2_MOVI	MATCH_R2_OP (ADDI) | SET_IW_F2I16_A (0)
+#define MASK_R2_MOVI	MASK_R2_OP | IW_F2I16_A_SHIFTED_MASK
+#define MATCH_R2_MOVUI	MATCH_R2_OP (ORI) | SET_IW_F2I16_A (0)
+#define MASK_R2_MOVUI	MASK_R2_OP | IW_F2I16_A_SHIFTED_MASK
+#define MATCH_R2_MOV_N	MATCH_R2_OP (MOV_N)
+#define MASK_R2_MOV_N	MASK_R2_OP
+#define MATCH_R2_MOVI_N	MATCH_R2_OP (MOVI_N)
+#define MASK_R2_MOVI_N	MASK_R2_OP
+#define MATCH_R2_MUL	MATCH_R2_OPX0 (MUL)
+#define MASK_R2_MUL	MASK_R2_OPX0
+#define MATCH_R2_MULI	MATCH_R2_OP (MULI)
+#define MASK_R2_MULI	MASK_R2_OP
+#define MATCH_R2_MULXSS	MATCH_R2_OPX0 (MULXSS)
+#define MASK_R2_MULXSS	MASK_R2_OPX0
+#define MATCH_R2_MULXSU	MATCH_R2_OPX0 (MULXSU)
+#define MASK_R2_MULXSU	MASK_R2_OPX0
+#define MATCH_R2_MULXUU	MATCH_R2_OPX0 (MULXUU)
+#define MASK_R2_MULXUU	MASK_R2_OPX0
+#define MATCH_R2_NEG_N	MATCH_R2_R_N (NEG_N)
+#define MASK_R2_NEG_N	MASK_R2_R_N
+#define MATCH_R2_NEXTPC	MATCH_R2_OPX (NEXTPC, 0, 0, 0)
+#define MASK_R2_NEXTPC	MASK_R2_OPX (1, 1, 0, 1)
+#define MATCH_R2_NOP	MATCH_R2_OPX (ADD, 0, 0, 0)
+#define MASK_R2_NOP	MASK_R2_OPX (1, 1, 1, 1)
+#define MATCH_R2_NOP_N	(MATCH_R2_OP (MOV_N) | SET_IW_F2_A (0) | SET_IW_F2_B (0))
+#define MASK_R2_NOP_N	(MASK_R2_OP | IW_F2_A_SHIFTED_MASK | IW_F2_B_SHIFTED_MASK)
+#define MATCH_R2_NOR	MATCH_R2_OPX0 (NOR)
+#define MASK_R2_NOR	MASK_R2_OPX0
+#define MATCH_R2_NOT_N	MATCH_R2_R_N (NOT_N)
+#define MASK_R2_NOT_N	MASK_R2_R_N
+#define MATCH_R2_OR	MATCH_R2_OPX0 (OR)
+#define MASK_R2_OR	MASK_R2_OPX0
+#define MATCH_R2_OR_N	MATCH_R2_R_N (OR_N)
+#define MASK_R2_OR_N	MASK_R2_R_N
+#define MATCH_R2_ORHI	MATCH_R2_OP (ORHI)
+#define MASK_R2_ORHI	MASK_R2_OP
+#define MATCH_R2_ORI	MATCH_R2_OP (ORI)
+#define MASK_R2_ORI	MASK_R2_OP
+#define MATCH_R2_POP_N	(MATCH_R2_OP (PP_N) | SET_IW_L5I4X1_X (R2_PP_N_POP_N))
+#define MASK_R2_POP_N	(MASK_R2_OP | IW_L5I4X1_X_SHIFTED_MASK)
+#define MATCH_R2_PUSH_N	(MATCH_R2_OP (PP_N) | SET_IW_L5I4X1_X (R2_PP_N_PUSH_N))
+#define MASK_R2_PUSH_N	(MASK_R2_OP | IW_L5I4X1_X_SHIFTED_MASK)
+#define MATCH_R2_RDCTL	MATCH_R2_OPX (RDCTL, 0, 0, 0)
+#define MASK_R2_RDCTL	MASK_R2_OPX (1, 1, 0, 0)
+#define MATCH_R2_RDPRS	MATCH_R2_I12 (RDPRS)
+#define MASK_R2_RDPRS	MASK_R2_I12
+#define MATCH_R2_RET	MATCH_R2_OPX (RET, 0x1f, 0, 0)
+#define MASK_R2_RET	MASK_R2_OPX (1, 1, 1, 1)
+#define MATCH_R2_RET_N	(MATCH_R2_R_N (RET_N) | SET_IW_X2L5_IMM5 (0))
+#define MASK_R2_RET_N	(MASK_R2_R_N | IW_X2L5_IMM5_SHIFTED_MASK)
+#define MATCH_R2_ROL	MATCH_R2_OPX0 (ROL)
+#define MASK_R2_ROL	MASK_R2_OPX0
+#define MATCH_R2_ROLI	MATCH_R2_OPX (ROLI, 0, 0, 0)
+#define MASK_R2_ROLI	MASK_R2_OPX (0, 1, 0, 0)
+#define MATCH_R2_ROR	MATCH_R2_OPX0 (ROR)
+#define MASK_R2_ROR	MASK_R2_OPX0
+#define MATCH_R2_SLL	MATCH_R2_OPX0 (SLL)
+#define MASK_R2_SLL	MASK_R2_OPX0
+#define MATCH_R2_SLLI	MATCH_R2_OPX (SLLI, 0, 0, 0)
+#define MASK_R2_SLLI	MASK_R2_OPX (0, 1, 0, 0)
+#define MATCH_R2_SLL_N	MATCH_R2_R_N (SLL_N)
+#define MASK_R2_SLL_N	MASK_R2_R_N
+#define MATCH_R2_SLLI_N	(MATCH_R2_OP (SHI_N) | SET_IW_T2X1L3_X (R2_SHI_N_SLLI_N))
+#define MASK_R2_SLLI_N	(MASK_R2_OP | IW_T2X1L3_X_SHIFTED_MASK)
+#define MATCH_R2_SPADDI_N	MATCH_R2_OP (SPADDI_N)
+#define MASK_R2_SPADDI_N	MASK_R2_OP
+#define MATCH_R2_SPDECI_N	(MATCH_R2_OP (SPI_N) | SET_IW_X1I7_X (R2_SPI_N_SPDECI_N))
+#define MASK_R2_SPDECI_N	(MASK_R2_OP | IW_X1I7_X_SHIFTED_MASK)
+#define MATCH_R2_SPINCI_N	(MATCH_R2_OP (SPI_N) | SET_IW_X1I7_X (R2_SPI_N_SPINCI_N))
+#define MASK_R2_SPINCI_N	(MASK_R2_OP | IW_X1I7_X_SHIFTED_MASK)
+#define MATCH_R2_SRA	MATCH_R2_OPX0 (SRA)
+#define MASK_R2_SRA	MASK_R2_OPX0
+#define MATCH_R2_SRAI	MATCH_R2_OPX (SRAI, 0, 0, 0)
+#define MASK_R2_SRAI	MASK_R2_OPX (0, 1, 0, 0)
+#define MATCH_R2_SRL	MATCH_R2_OPX0 (SRL)
+#define MASK_R2_SRL	MASK_R2_OPX0
+#define MATCH_R2_SRLI	MATCH_R2_OPX (SRLI, 0, 0, 0)
+#define MASK_R2_SRLI	MASK_R2_OPX (0, 1, 0, 0)
+#define MATCH_R2_SRL_N	MATCH_R2_R_N (SRL_N)
+#define MASK_R2_SRL_N	MASK_R2_R_N
+#define MATCH_R2_SRLI_N	(MATCH_R2_OP (SHI_N) | SET_IW_T2X1L3_X (R2_SHI_N_SRLI_N))
+#define MASK_R2_SRLI_N	(MASK_R2_OP | IW_T2X1L3_X_SHIFTED_MASK)
+#define MATCH_R2_STB	MATCH_R2_OP (STB)
+#define MASK_R2_STB	MASK_R2_OP
+#define MATCH_R2_STBIO	MATCH_R2_I12 (STBIO)
+#define MASK_R2_STBIO	MASK_R2_I12
+#define MATCH_R2_STB_N	MATCH_R2_OP (STB_N)
+#define MASK_R2_STB_N	MASK_R2_OP
+#define MATCH_R2_STBZ_N	(MATCH_R2_OP (STZ_N) | SET_IW_T1X1I6_X (R2_STZ_N_STBZ_N))
+#define MASK_R2_STBZ_N	(MASK_R2_OP | IW_T1X1I6_X_SHIFTED_MASK)
+#define MATCH_R2_STEX	MATCH_R2_OPX0 (STEX)
+#define MASK_R2_STEX	MASK_R2_OPX0
+#define MATCH_R2_STH	MATCH_R2_OP (STH)
+#define MASK_R2_STH	MASK_R2_OP
+#define MATCH_R2_STHIO	MATCH_R2_I12 (STHIO)
+#define MASK_R2_STHIO	MASK_R2_I12
+#define MATCH_R2_STH_N	MATCH_R2_OP (STH_N)
+#define MASK_R2_STH_N	MASK_R2_OP
+#define MATCH_R2_STSEX	MATCH_R2_OPX0 (STSEX)
+#define MASK_R2_STSEX	MASK_R2_OPX0
+#define MATCH_R2_STW	MATCH_R2_OP (STW)
+#define MASK_R2_STW	MASK_R2_OP
+#define MATCH_R2_STWIO	MATCH_R2_I12 (STWIO)
+#define MASK_R2_STWIO	MASK_R2_I12
+#define MATCH_R2_STWM	MATCH_R2_I12 (STWM)
+#define MASK_R2_STWM	MASK_R2_I12
+#define MATCH_R2_STWSP_N	MATCH_R2_OP (STWSP_N)
+#define MASK_R2_STWSP_N	MASK_R2_OP
+#define MATCH_R2_STW_N	MATCH_R2_OP (STW_N)
+#define MASK_R2_STW_N	MASK_R2_OP
+#define MATCH_R2_STWZ_N	MATCH_R2_OP (STZ_N)
+#define MASK_R2_STWZ_N	MASK_R2_OP
+#define MATCH_R2_SUB	MATCH_R2_OPX0 (SUB)
+#define MASK_R2_SUB	MASK_R2_OPX0
+#define MATCH_R2_SUBI	MATCH_R2_OP (ADDI)
+#define MASK_R2_SUBI	MASK_R2_OP
+#define MATCH_R2_SUB_N	(MATCH_R2_OP (AS_N) | SET_IW_T3X1_X (R2_AS_N_SUB_N))
+#define MASK_R2_SUB_N	(MASK_R2_OP | IW_T3X1_X_SHIFTED_MASK)
+#define MATCH_R2_SUBI_N	(MATCH_R2_OP (ASI_N) | SET_IW_T2X1I3_X (R2_ASI_N_SUBI_N))
+#define MASK_R2_SUBI_N	(MASK_R2_OP | IW_T2X1I3_X_SHIFTED_MASK)
+#define MATCH_R2_SYNC	MATCH_R2_OPX (SYNC, 0, 0, 0)
+#define MASK_R2_SYNC	MASK_R2_OPX (1, 1, 1, 1)
+#define MATCH_R2_TRAP	MATCH_R2_OPX (TRAP, 0, 0, 0x1d)
+#define MASK_R2_TRAP	MASK_R2_OPX (1, 1, 1, 0)
+#define MATCH_R2_TRAP_N	MATCH_R2_R_N (TRAP_N)
+#define MASK_R2_TRAP_N	MASK_R2_R_N
+#define MATCH_R2_WRCTL	MATCH_R2_OPX (WRCTL, 0, 0, 0)
+#define MASK_R2_WRCTL	MASK_R2_OPX (0, 1, 1, 0)
+#define MATCH_R2_WRPIE	MATCH_R2_OPX (WRPIE, 0, 0, 0)
+#define MASK_R2_WRPIE	MASK_R2_OPX (0, 1, 0, 1)
+#define MATCH_R2_WRPRS	MATCH_R2_OPX (WRPRS, 0, 0, 0)
+#define MASK_R2_WRPRS	MASK_R2_OPX (0, 1, 0, 1)
+#define MATCH_R2_XOR	MATCH_R2_OPX0 (XOR)
+#define MASK_R2_XOR	MASK_R2_OPX0
+#define MATCH_R2_XORHI	MATCH_R2_OP (XORHI)
+#define MASK_R2_XORHI	MASK_R2_OP
+#define MATCH_R2_XORI	MATCH_R2_OP (XORI)
+#define MASK_R2_XORI	MASK_R2_OP
+#define MATCH_R2_XOR_N	MATCH_R2_R_N (XOR_N)
+#define MASK_R2_XOR_N	MASK_R2_R_N
+
+#endif /* _NIOS2R2_H */
+
+
+/* These are the data structures used to hold the instruction information.  */
+extern const struct nios2_opcode nios2_r1_opcodes[];
+extern const int nios2_num_r1_opcodes;
+extern const struct nios2_opcode nios2_r2_opcodes[];
+extern const int nios2_num_r2_opcodes;
+extern struct nios2_opcode *nios2_opcodes;
+extern int nios2_num_opcodes;
+
+/* 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;
+
+/* Return the opcode descriptor for a single instruction.  */
+extern const struct nios2_opcode *
+nios2_find_opcode_hash (unsigned long, unsigned long);
+
+/* Lookup tables for R2 immediate decodings.  */
+extern unsigned int nios2_r2_asi_n_mappings[];
+extern const int nios2_num_r2_asi_n_mappings;
+extern unsigned int nios2_r2_shi_n_mappings[];
+extern const int nios2_num_r2_shi_n_mappings;
+extern unsigned int nios2_r2_andi_n_mappings[];
+extern const int nios2_num_r2_andi_n_mappings;
+
+/* Lookup table for 3-bit register decodings.  */
+extern int nios2_r2_reg3_mappings[];
+extern const int nios2_num_r2_reg3_mappings;
+
+/* Lookup table for REG_RANGE value list decodings.  */
+extern unsigned long nios2_r2_reg_range_mappings[];
+extern const int nios2_num_r2_reg_range_mappings;
+
+#endif /* _NIOS2_H */
+
+/*#include "sysdep.h"
+#include <stdio.h>
+#include "opcode/nios2.h"
+*/
+/* Register string table */
+
+const struct nios2_reg nios2_builtin_regs[] = {
+  /* Standard register names.  */
+  {"zero", 0, REG_NORMAL},
+  {"at", 1, REG_NORMAL},			/* assembler temporary */
+  {"r2", 2, REG_NORMAL | REG_3BIT | REG_LDWM},
+  {"r3", 3, REG_NORMAL | REG_3BIT | REG_LDWM},
+  {"r4", 4, REG_NORMAL | REG_3BIT | REG_LDWM},
+  {"r5", 5, REG_NORMAL | REG_3BIT | REG_LDWM},
+  {"r6", 6, REG_NORMAL | REG_3BIT | REG_LDWM},
+  {"r7", 7, REG_NORMAL | REG_3BIT | REG_LDWM},
+  {"r8", 8, REG_NORMAL | REG_LDWM},
+  {"r9", 9, REG_NORMAL | REG_LDWM},
+  {"r10", 10, REG_NORMAL | REG_LDWM},
+  {"r11", 11, REG_NORMAL | REG_LDWM},
+  {"r12", 12, REG_NORMAL | REG_LDWM},
+  {"r13", 13, REG_NORMAL | REG_LDWM},
+  {"r14", 14, REG_NORMAL | REG_LDWM},
+  {"r15", 15, REG_NORMAL | REG_LDWM},
+  {"r16", 16, REG_NORMAL | REG_3BIT | REG_LDWM | REG_POP},
+  {"r17", 17, REG_NORMAL | REG_3BIT | REG_LDWM | REG_POP},
+  {"r18", 18, REG_NORMAL | REG_LDWM | REG_POP},
+  {"r19", 19, REG_NORMAL | REG_LDWM | REG_POP},
+  {"r20", 20, REG_NORMAL | REG_LDWM | REG_POP},
+  {"r21", 21, REG_NORMAL | REG_LDWM | REG_POP},
+  {"r22", 22, REG_NORMAL | REG_LDWM | REG_POP},
+  {"r23", 23, REG_NORMAL | REG_LDWM | REG_POP},
+  {"et", 24, REG_NORMAL},
+  {"bt", 25, REG_NORMAL},
+  {"gp", 26, REG_NORMAL},			/* global pointer */
+  {"sp", 27, REG_NORMAL},			/* stack pointer */
+  {"fp", 28, REG_NORMAL | REG_LDWM | REG_POP},	/* frame pointer */
+  {"ea", 29, REG_NORMAL},			/* exception return address */
+  {"sstatus", 30, REG_NORMAL},			/* saved processor status */
+  {"ra", 31, REG_NORMAL | REG_LDWM | REG_POP},	/* return address */
+
+  /* Alternative names for special registers.  */
+  {"r0", 0, REG_NORMAL},
+  {"r1", 1, REG_NORMAL},
+  {"r24", 24, REG_NORMAL},
+  {"r25", 25, REG_NORMAL},
+  {"r26", 26, REG_NORMAL},
+  {"r27", 27, REG_NORMAL},
+  {"r28", 28, REG_NORMAL | REG_LDWM | REG_POP},
+  {"r29", 29, REG_NORMAL},
+  {"r30", 30, REG_NORMAL},
+  {"ba", 30, REG_NORMAL},			/* breakpoint return address */
+  {"r31", 31, REG_NORMAL | REG_LDWM | REG_POP},
+
+  /* Control register names.  */
+  {"status", 0, REG_CONTROL},
+  {"estatus", 1, REG_CONTROL},
+  {"bstatus", 2, REG_CONTROL},
+  {"ienable", 3, REG_CONTROL},
+  {"ipending", 4, REG_CONTROL},
+  {"cpuid", 5, REG_CONTROL},
+  {"ctl6", 6, REG_CONTROL},
+  {"exception", 7, REG_CONTROL},
+  {"pteaddr", 8, REG_CONTROL},
+  {"tlbacc", 9, REG_CONTROL},
+  {"tlbmisc", 10, REG_CONTROL},
+  {"eccinj", 11, REG_CONTROL},
+  {"badaddr", 12, REG_CONTROL},
+  {"config", 13, REG_CONTROL},
+  {"mpubase", 14, REG_CONTROL},
+  {"mpuacc", 15, REG_CONTROL},
+  {"ctl16", 16, REG_CONTROL},
+  {"ctl17", 17, REG_CONTROL},
+  {"ctl18", 18, REG_CONTROL},
+  {"ctl19", 19, REG_CONTROL},
+  {"ctl20", 20, REG_CONTROL},
+  {"ctl21", 21, REG_CONTROL},
+  {"ctl22", 22, REG_CONTROL},
+  {"ctl23", 23, REG_CONTROL},
+  {"ctl24", 24, REG_CONTROL},
+  {"ctl25", 25, REG_CONTROL},
+  {"ctl26", 26, REG_CONTROL},
+  {"ctl27", 27, REG_CONTROL},
+  {"ctl28", 28, REG_CONTROL},
+  {"ctl29", 29, REG_CONTROL},
+  {"ctl30", 30, REG_CONTROL},
+  {"ctl31", 31, REG_CONTROL},
+
+  /* Alternative names for special control registers.  */
+  {"ctl0", 0, REG_CONTROL},
+  {"ctl1", 1, REG_CONTROL},
+  {"ctl2", 2, REG_CONTROL},
+  {"ctl3", 3, REG_CONTROL},
+  {"ctl4", 4, REG_CONTROL},
+  {"ctl5", 5, REG_CONTROL},
+  {"ctl7", 7, REG_CONTROL},
+  {"ctl8", 8, REG_CONTROL},
+  {"ctl9", 9, REG_CONTROL},
+  {"ctl10", 10, REG_CONTROL},
+  {"ctl11", 11, REG_CONTROL},
+  {"ctl12", 12, REG_CONTROL},
+  {"ctl13", 13, REG_CONTROL},
+  {"ctl14", 14, REG_CONTROL},
+  {"ctl15", 15, REG_CONTROL},
+
+  /* Coprocessor register names.  */
+  {"c0", 0, REG_COPROCESSOR},
+  {"c1", 1, REG_COPROCESSOR},
+  {"c2", 2, REG_COPROCESSOR},
+  {"c3", 3, REG_COPROCESSOR},
+  {"c4", 4, REG_COPROCESSOR},
+  {"c5", 5, REG_COPROCESSOR},
+  {"c6", 6, REG_COPROCESSOR},
+  {"c7", 7, REG_COPROCESSOR},
+  {"c8", 8, REG_COPROCESSOR},
+  {"c9", 9, REG_COPROCESSOR},
+  {"c10", 10, REG_COPROCESSOR},
+  {"c11", 11, REG_COPROCESSOR},
+  {"c12", 12, REG_COPROCESSOR},
+  {"c13", 13, REG_COPROCESSOR},
+  {"c14", 14, REG_COPROCESSOR},
+  {"c15", 15, REG_COPROCESSOR},
+  {"c16", 16, REG_COPROCESSOR},
+  {"c17", 17, REG_COPROCESSOR},
+  {"c18", 18, REG_COPROCESSOR},
+  {"c19", 19, REG_COPROCESSOR},
+  {"c20", 20, REG_COPROCESSOR},
+  {"c21", 21, REG_COPROCESSOR},
+  {"c22", 22, REG_COPROCESSOR},
+  {"c23", 23, REG_COPROCESSOR},
+  {"c24", 24, REG_COPROCESSOR},
+  {"c25", 25, REG_COPROCESSOR},
+  {"c26", 26, REG_COPROCESSOR},
+  {"c27", 27, REG_COPROCESSOR},
+  {"c28", 28, REG_COPROCESSOR},
+  {"c29", 29, REG_COPROCESSOR},
+  {"c30", 30, REG_COPROCESSOR},
+  {"c31", 31, REG_COPROCESSOR},
+};
+
+#define NIOS2_NUM_REGS \
+       ((sizeof nios2_builtin_regs) / (sizeof (nios2_builtin_regs[0])))
+const int nios2_num_builtin_regs = NIOS2_NUM_REGS;
+
+/* This is not const in order 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
+
+/* This is the opcode table used by the Nios II GNU as, disassembler
+   and GDB.  */
+const struct nios2_opcode nios2_r1_opcodes[] =
+{
+  /* { name, args, args_test, num_args, size, format,
+       match, mask, pinfo, overflow } */
+  {"add", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_ADD, MASK_R1_ADD, 0, no_overflow},
+  {"addi", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+   MATCH_R1_ADDI, MASK_R1_ADDI, 0, signed_immed16_overflow},
+  {"and", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_AND, MASK_R1_AND, 0, no_overflow},
+  {"andhi", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+   MATCH_R1_ANDHI, MASK_R1_ANDHI, 0, unsigned_immed16_overflow},
+  {"andi", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+   MATCH_R1_ANDI, MASK_R1_ANDI, 0, unsigned_immed16_overflow},
+  {"beq", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+   MATCH_R1_BEQ, MASK_R1_BEQ, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bge", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+   MATCH_R1_BGE, MASK_R1_BGE, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bgeu", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+   MATCH_R1_BGEU, MASK_R1_BGEU, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bgt", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+   MATCH_R1_BGT, MASK_R1_BGT,
+   NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bgtu", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+   MATCH_R1_BGTU, MASK_R1_BGTU,
+   NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"ble", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+   MATCH_R1_BLE, MASK_R1_BLE,
+   NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bleu", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+   MATCH_R1_BLEU, MASK_R1_BLEU,
+   NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"blt", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+   MATCH_R1_BLT, MASK_R1_BLT, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bltu", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+   MATCH_R1_BLTU, MASK_R1_BLTU, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bne", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+   MATCH_R1_BNE, MASK_R1_BNE, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"br", "o", "o,E", 1, 4, iw_i_type,
+   MATCH_R1_BR, MASK_R1_BR, NIOS2_INSN_UBRANCH, branch_target_overflow},
+  {"break", "j", "j,E", 1, 4, iw_r_type,
+   MATCH_R1_BREAK, MASK_R1_BREAK, NIOS2_INSN_OPTARG, no_overflow},
+  {"bret", "", "E", 0, 4, iw_r_type,
+   MATCH_R1_BRET, MASK_R1_BRET, 0, no_overflow},
+  {"call", "m", "m,E", 1, 4, iw_j_type,
+   MATCH_R1_CALL, MASK_R1_CALL, NIOS2_INSN_CALL, call_target_overflow},
+  {"callr", "s", "s,E", 1, 4, iw_r_type,
+   MATCH_R1_CALLR, MASK_R1_CALLR, 0, no_overflow},
+  {"cmpeq", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_CMPEQ, MASK_R1_CMPEQ, 0, no_overflow},
+  {"cmpeqi", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+   MATCH_R1_CMPEQI, MASK_R1_CMPEQI, 0, signed_immed16_overflow},
+  {"cmpge", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_CMPGE, MASK_R1_CMPGE, 0, no_overflow},
+  {"cmpgei", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+   MATCH_R1_CMPGEI, MASK_R1_CMPGEI, 0, signed_immed16_overflow},
+  {"cmpgeu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_CMPGEU, MASK_R1_CMPGEU, 0, no_overflow},
+  {"cmpgeui", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+   MATCH_R1_CMPGEUI, MASK_R1_CMPGEUI, 0, unsigned_immed16_overflow},
+  {"cmpgt", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_CMPGT, MASK_R1_CMPGT, NIOS2_INSN_MACRO, no_overflow},
+  {"cmpgti", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+   MATCH_R1_CMPGTI, MASK_R1_CMPGTI, NIOS2_INSN_MACRO, signed_immed16_overflow},
+  {"cmpgtu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_CMPGTU, MASK_R1_CMPGTU, NIOS2_INSN_MACRO, no_overflow},
+  {"cmpgtui", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+   MATCH_R1_CMPGTUI, MASK_R1_CMPGTUI,
+   NIOS2_INSN_MACRO, unsigned_immed16_overflow},
+  {"cmple", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_CMPLE, MASK_R1_CMPLE, NIOS2_INSN_MACRO, no_overflow},
+  {"cmplei", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+   MATCH_R1_CMPLEI, MASK_R1_CMPLEI, NIOS2_INSN_MACRO, signed_immed16_overflow},
+  {"cmpleu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_CMPLEU, MASK_R1_CMPLEU, NIOS2_INSN_MACRO, no_overflow},
+  {"cmpleui", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+   MATCH_R1_CMPLEUI, MASK_R1_CMPLEUI,
+   NIOS2_INSN_MACRO, unsigned_immed16_overflow},
+  {"cmplt", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_CMPLT, MASK_R1_CMPLT, 0, no_overflow},
+  {"cmplti", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+   MATCH_R1_CMPLTI, MASK_R1_CMPLTI, 0, signed_immed16_overflow},
+  {"cmpltu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_CMPLTU, MASK_R1_CMPLTU, 0, no_overflow},
+  {"cmpltui", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+   MATCH_R1_CMPLTUI, MASK_R1_CMPLTUI, 0, unsigned_immed16_overflow},
+  {"cmpne", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_CMPNE, MASK_R1_CMPNE, 0, no_overflow},
+  {"cmpnei", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+   MATCH_R1_CMPNEI, MASK_R1_CMPNEI, 0, signed_immed16_overflow},
+  {"custom", "l,d,s,t", "l,d,s,t,E", 4, 4, iw_custom_type,
+   MATCH_R1_CUSTOM, MASK_R1_CUSTOM, 0, custom_opcode_overflow},
+  {"div", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_DIV, MASK_R1_DIV, 0, no_overflow},
+  {"divu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_DIVU, MASK_R1_DIVU, 0, no_overflow},
+  {"eret", "", "E", 0, 4, iw_r_type,
+   MATCH_R1_ERET, MASK_R1_ERET, 0, no_overflow},
+  {"flushd", "i(s)", "i(s),E", 2, 4, iw_i_type,
+   MATCH_R1_FLUSHD, MASK_R1_FLUSHD, 0, address_offset_overflow},
+  {"flushda", "i(s)", "i(s),E", 2, 4, iw_i_type,
+   MATCH_R1_FLUSHDA, MASK_R1_FLUSHDA, 0, address_offset_overflow},
+  {"flushi", "s", "s,E", 1, 4, iw_r_type,
+   MATCH_R1_FLUSHI, MASK_R1_FLUSHI, 0, no_overflow},
+  {"flushp", "", "E", 0, 4, iw_r_type,
+   MATCH_R1_FLUSHP, MASK_R1_FLUSHP, 0, no_overflow},
+  {"initd", "i(s)", "i(s),E", 2, 4, iw_i_type,
+   MATCH_R1_INITD, MASK_R1_INITD, 0, address_offset_overflow},
+  {"initda", "i(s)", "i(s),E", 2, 4, iw_i_type,
+   MATCH_R1_INITDA, MASK_R1_INITDA, 0, address_offset_overflow},
+  {"initi", "s", "s,E", 1, 4, iw_r_type,
+   MATCH_R1_INITI, MASK_R1_INITI, 0, no_overflow},
+  {"jmp", "s", "s,E", 1, 4, iw_r_type,
+   MATCH_R1_JMP, MASK_R1_JMP, 0, no_overflow},
+  {"jmpi", "m", "m,E", 1, 4, iw_j_type,
+   MATCH_R1_JMPI, MASK_R1_JMPI, 0, call_target_overflow},
+  {"ldb", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_LDB, MASK_R1_LDB, 0, address_offset_overflow},
+  {"ldbio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_LDBIO, MASK_R1_LDBIO, 0, address_offset_overflow},
+  {"ldbu", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_LDBU, MASK_R1_LDBU, 0, address_offset_overflow},
+  {"ldbuio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_LDBUIO, MASK_R1_LDBUIO, 0, address_offset_overflow},
+  {"ldh", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_LDH, MASK_R1_LDH, 0, address_offset_overflow},
+  {"ldhio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_LDHIO, MASK_R1_LDHIO, 0, address_offset_overflow},
+  {"ldhu", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_LDHU, MASK_R1_LDHU, 0, address_offset_overflow},
+  {"ldhuio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_LDHUIO, MASK_R1_LDHUIO, 0, address_offset_overflow},
+  {"ldw", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_LDW, MASK_R1_LDW, 0, address_offset_overflow},
+  {"ldwio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_LDWIO, MASK_R1_LDWIO, 0, address_offset_overflow},
+  {"mov", "d,s", "d,s,E", 2, 4, iw_r_type,
+   MATCH_R1_MOV, MASK_R1_MOV, NIOS2_INSN_MACRO_MOV, no_overflow},
+  {"movhi", "t,u", "t,u,E", 2, 4, iw_i_type,
+   MATCH_R1_MOVHI, MASK_R1_MOVHI,
+   NIOS2_INSN_MACRO_MOVI, unsigned_immed16_overflow},
+  {"movi", "t,i", "t,i,E", 2, 4, iw_i_type,
+   MATCH_R1_MOVI, MASK_R1_MOVI, NIOS2_INSN_MACRO_MOVI, signed_immed16_overflow},
+  {"movia", "t,o", "t,o,E", 2, 4, iw_i_type,
+   MATCH_R1_ORHI, MASK_R1_ORHI, NIOS2_INSN_MACRO_MOVIA, no_overflow},
+  {"movui", "t,u", "t,u,E", 2, 4, iw_i_type,
+   MATCH_R1_MOVUI, MASK_R1_MOVUI,
+   NIOS2_INSN_MACRO_MOVI, unsigned_immed16_overflow},
+  {"mul", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_MUL, MASK_R1_MUL, 0, no_overflow},
+  {"muli", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+   MATCH_R1_MULI, MASK_R1_MULI, 0, signed_immed16_overflow},
+  {"mulxss", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_MULXSS, MASK_R1_MULXSS, 0, no_overflow},
+  {"mulxsu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_MULXSU, MASK_R1_MULXSU, 0, no_overflow},
+  {"mulxuu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_MULXUU, MASK_R1_MULXUU, 0, no_overflow},
+  {"nextpc", "d", "d,E", 1, 4, iw_r_type,
+   MATCH_R1_NEXTPC, MASK_R1_NEXTPC, 0, no_overflow},
+  {"nop", "", "E", 0, 4, iw_r_type,
+   MATCH_R1_NOP, MASK_R1_NOP, NIOS2_INSN_MACRO_MOV, no_overflow},
+  {"nor", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_NOR, MASK_R1_NOR, 0, no_overflow},
+  {"or", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_OR, MASK_R1_OR, 0, no_overflow},
+  {"orhi", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+   MATCH_R1_ORHI, MASK_R1_ORHI, 0, unsigned_immed16_overflow},
+  {"ori", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+   MATCH_R1_ORI, MASK_R1_ORI, 0, unsigned_immed16_overflow},
+  {"rdctl", "d,c", "d,c,E", 2, 4, iw_r_type,
+   MATCH_R1_RDCTL, MASK_R1_RDCTL, 0, no_overflow},
+  {"rdprs", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+   MATCH_R1_RDPRS, MASK_R1_RDPRS, 0, signed_immed16_overflow},
+  {"ret", "", "E", 0, 4, iw_r_type,
+   MATCH_R1_RET, MASK_R1_RET, 0, no_overflow},
+  {"rol", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_ROL, MASK_R1_ROL, 0, no_overflow},
+  {"roli", "d,s,j", "d,s,j,E", 3, 4, iw_r_type,
+   MATCH_R1_ROLI, MASK_R1_ROLI, 0, unsigned_immed5_overflow},
+  {"ror", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_ROR, MASK_R1_ROR, 0, no_overflow},
+  {"sll", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_SLL, MASK_R1_SLL, 0, no_overflow},
+  {"slli", "d,s,j", "d,s,j,E", 3, 4, iw_r_type,
+   MATCH_R1_SLLI, MASK_R1_SLLI, 0, unsigned_immed5_overflow},
+  {"sra", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_SRA, MASK_R1_SRA, 0, no_overflow},
+  {"srai", "d,s,j", "d,s,j,E", 3, 4, iw_r_type,
+   MATCH_R1_SRAI, MASK_R1_SRAI, 0, unsigned_immed5_overflow},
+  {"srl", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_SRL, MASK_R1_SRL, 0, no_overflow},
+  {"srli", "d,s,j", "d,s,j,E", 3, 4, iw_r_type,
+   MATCH_R1_SRLI, MASK_R1_SRLI, 0, unsigned_immed5_overflow},
+  {"stb", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_STB, MASK_R1_STB, 0, address_offset_overflow},
+  {"stbio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_STBIO, MASK_R1_STBIO, 0, address_offset_overflow},
+  {"sth", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_STH, MASK_R1_STH, 0, address_offset_overflow},
+  {"sthio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_STHIO, MASK_R1_STHIO, 0, address_offset_overflow},
+  {"stw", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_STW, MASK_R1_STW, 0, address_offset_overflow},
+  {"stwio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+   MATCH_R1_STWIO, MASK_R1_STWIO, 0, address_offset_overflow},
+  {"sub", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_SUB, MASK_R1_SUB, 0, no_overflow},
+  {"subi", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+   MATCH_R1_SUBI, MASK_R1_SUBI, NIOS2_INSN_MACRO, signed_immed16_overflow},
+  {"sync", "", "E", 0, 4, iw_r_type,
+   MATCH_R1_SYNC, MASK_R1_SYNC, 0, no_overflow},
+  {"trap", "j", "j,E", 1, 4, iw_r_type,
+   MATCH_R1_TRAP, MASK_R1_TRAP, NIOS2_INSN_OPTARG, no_overflow},
+  {"wrctl", "c,s", "c,s,E", 2, 4, iw_r_type,
+   MATCH_R1_WRCTL, MASK_R1_WRCTL, 0, no_overflow},
+  {"wrprs", "d,s", "d,s,E", 2, 4, iw_r_type,
+   MATCH_R1_WRPRS, MASK_R1_WRPRS, 0, no_overflow},
+  {"xor", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+   MATCH_R1_XOR, MASK_R1_XOR, 0, no_overflow},
+  {"xorhi", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+   MATCH_R1_XORHI, MASK_R1_XORHI, 0, unsigned_immed16_overflow},
+  {"xori", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+   MATCH_R1_XORI, MASK_R1_XORI, 0, unsigned_immed16_overflow}
+};
+
+#define NIOS2_NUM_R1_OPCODES \
+       ((sizeof nios2_r1_opcodes) / (sizeof (nios2_r1_opcodes[0])))
+const int nios2_num_r1_opcodes = NIOS2_NUM_R1_OPCODES;
+
+
+const struct nios2_opcode nios2_r2_opcodes[] =
+{
+  /* { name, args, args_test, num_args, size, format,
+       match, mask, pinfo, overflow } */
+  {"add", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_ADD, MASK_R2_ADD, 0, no_overflow},
+  {"addi", "t,s,i", "t,s,i,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_ADDI, MASK_R2_ADDI, 0, signed_immed16_overflow},
+  {"add.n", "D,S,T", "D,S,T,E", 3, 2, iw_T3X1_type,
+   MATCH_R2_ADD_N, MASK_R2_ADD_N, 0, no_overflow},
+  {"addi.n", "D,S,e", "D,S,e,E", 3, 2, iw_T2X1I3_type,
+   MATCH_R2_ADDI_N, MASK_R2_ADDI_N, 0, enumeration_overflow},
+  {"and", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_AND, MASK_R2_AND, 0, no_overflow},
+  {"andchi", "t,s,u", "t,s,u,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_ANDCHI, MASK_R2_ANDCHI, 0, unsigned_immed16_overflow},
+  {"andci", "t,s,u", "t,s,u,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_ANDCI, MASK_R2_ANDCI, 0, unsigned_immed16_overflow},
+  {"andhi", "t,s,u", "t,s,u,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_ANDHI, MASK_R2_ANDHI, 0, unsigned_immed16_overflow},
+  {"andi", "t,s,u", "t,s,u,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_ANDI, MASK_R2_ANDI, 0, unsigned_immed16_overflow},
+  {"andi.n", "T,S,g", "T,S,g,E", 3, 2, iw_T2I4_type,
+   MATCH_R2_ANDI_N, MASK_R2_ANDI_N, 0, enumeration_overflow},
+  {"and.n", "D,S,T", "D,S,T,E", 3, 2, iw_T2X3_type,
+   MATCH_R2_AND_N, MASK_R2_AND_N, 0, no_overflow},
+  {"beq", "s,t,o", "s,t,o,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_BEQ, MASK_R2_BEQ, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"beqz.n", "S,P", "S,P,E", 2, 2, iw_T1I7_type,
+   MATCH_R2_BEQZ_N, MASK_R2_BEQZ_N, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bge", "s,t,o", "s,t,o,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_BGE, MASK_R2_BGE, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bgeu", "s,t,o", "s,t,o,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_BGEU, MASK_R2_BGEU, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bgt", "s,t,o", "s,t,o,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_BGT, MASK_R2_BGT,
+   NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bgtu", "s,t,o", "s,t,o,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_BGTU, MASK_R2_BGTU,
+   NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"ble", "s,t,o", "s,t,o,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_BLE, MASK_R2_BLE,
+   NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bleu", "s,t,o", "s,t,o,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_BLEU, MASK_R2_BLEU,
+   NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"blt", "s,t,o", "s,t,o,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_BLT, MASK_R2_BLT, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bltu", "s,t,o", "s,t,o,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_BLTU, MASK_R2_BLTU, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bne", "s,t,o", "s,t,o,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_BNE, MASK_R2_BNE, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"bnez.n", "S,P", "S,P,E", 2, 2, iw_T1I7_type,
+   MATCH_R2_BNEZ_N, MASK_R2_BNEZ_N, NIOS2_INSN_CBRANCH, branch_target_overflow},
+  {"br", "o", "o,E", 1, 4, iw_F2I16_type,
+   MATCH_R2_BR, MASK_R2_BR, NIOS2_INSN_UBRANCH, branch_target_overflow},
+  {"break", "j", "j,E", 1, 4, iw_F3X6L5_type,
+   MATCH_R2_BREAK, MASK_R2_BREAK, NIOS2_INSN_OPTARG, no_overflow},
+  {"break.n", "j", "j,E", 1, 2, iw_X2L5_type,
+   MATCH_R2_BREAK_N, MASK_R2_BREAK_N, NIOS2_INSN_OPTARG, no_overflow},
+  {"bret", "", "E", 0, 4, iw_F3X6_type,
+   MATCH_R2_BRET, MASK_R2_BRET, 0, no_overflow},
+  {"br.n", "O", "O,E", 1, 2, iw_I10_type,
+   MATCH_R2_BR_N, MASK_R2_BR_N, NIOS2_INSN_UBRANCH, branch_target_overflow},
+  {"call", "m", "m,E", 1, 4, iw_L26_type,
+   MATCH_R2_CALL, MASK_R2_CALL, NIOS2_INSN_CALL, call_target_overflow},
+  {"callr", "s", "s,E", 1, 4, iw_F3X6_type,
+   MATCH_R2_CALLR, MASK_R2_CALLR, 0, no_overflow},
+  {"callr.n", "s", "s,E", 1, 2, iw_F1X1_type,
+   MATCH_R2_CALLR_N, MASK_R2_CALLR_N, 0, no_overflow},
+  {"cmpeq", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_CMPEQ, MASK_R2_CMPEQ, 0, no_overflow},
+  {"cmpeqi", "t,s,i", "t,s,i,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_CMPEQI, MASK_R2_CMPEQI, 0, signed_immed16_overflow},
+  {"cmpge", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_CMPGE, MASK_R2_CMPGE, 0, no_overflow},
+  {"cmpgei", "t,s,i", "t,s,i,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_CMPGEI, MASK_R2_CMPGEI, 0, signed_immed16_overflow},
+  {"cmpgeu", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_CMPGEU, MASK_R2_CMPGEU, 0, no_overflow},
+  {"cmpgeui", "t,s,u", "t,s,u,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_CMPGEUI, MASK_R2_CMPGEUI, 0, unsigned_immed16_overflow},
+  {"cmpgt", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_CMPGT, MASK_R2_CMPGT, NIOS2_INSN_MACRO, no_overflow},
+  {"cmpgti", "t,s,i", "t,s,i,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_CMPGTI, MASK_R2_CMPGTI, NIOS2_INSN_MACRO, signed_immed16_overflow},
+  {"cmpgtu", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_CMPGTU, MASK_R2_CMPGTU, NIOS2_INSN_MACRO, no_overflow},
+  {"cmpgtui", "t,s,u", "t,s,u,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_CMPGTUI, MASK_R2_CMPGTUI,
+   NIOS2_INSN_MACRO, unsigned_immed16_overflow},
+  {"cmple", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_CMPLE, MASK_R2_CMPLE, NIOS2_INSN_MACRO, no_overflow},
+  {"cmplei", "t,s,i", "t,s,i,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_CMPLEI, MASK_R2_CMPLEI, NIOS2_INSN_MACRO, signed_immed16_overflow},
+  {"cmpleu", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_CMPLEU, MASK_R2_CMPLEU, NIOS2_INSN_MACRO, no_overflow},
+  {"cmpleui", "t,s,u", "t,s,u,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_CMPLEUI, MASK_R2_CMPLEUI,
+   NIOS2_INSN_MACRO, unsigned_immed16_overflow},
+  {"cmplt", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_CMPLT, MASK_R2_CMPLT, 0, no_overflow},
+  {"cmplti", "t,s,i", "t,s,i,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_CMPLTI, MASK_R2_CMPLTI, 0, signed_immed16_overflow},
+  {"cmpltu", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_CMPLTU, MASK_R2_CMPLTU, 0, no_overflow},
+  {"cmpltui", "t,s,u", "t,s,u,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_CMPLTUI, MASK_R2_CMPLTUI, 0, unsigned_immed16_overflow},
+  {"cmpne", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_CMPNE, MASK_R2_CMPNE, 0, no_overflow},
+  {"cmpnei", "t,s,i", "t,s,i,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_CMPNEI, MASK_R2_CMPNEI, 0, signed_immed16_overflow},
+  {"custom", "l,d,s,t", "l,d,s,t,E", 4, 4, iw_F3X8_type,
+   MATCH_R2_CUSTOM, MASK_R2_CUSTOM, 0, custom_opcode_overflow},
+  {"div", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_DIV, MASK_R2_DIV, 0, no_overflow},
+  {"divu", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_DIVU, MASK_R2_DIVU, 0, no_overflow},
+  {"eni", "j", "j,E", 1, 4, iw_F3X6L5_type,
+   MATCH_R2_ENI, MASK_R2_ENI, NIOS2_INSN_OPTARG, no_overflow},
+  {"eret", "", "E", 0, 4, iw_F3X6_type,
+   MATCH_R2_ERET, MASK_R2_ERET, 0, no_overflow},
+  {"extract", "t,s,j,k", "t,s,j,k,E", 4, 4, iw_F2X6L10_type,
+   MATCH_R2_EXTRACT, MASK_R2_EXTRACT, 0, no_overflow},
+  {"flushd", "I(s)", "I(s),E", 2, 4, iw_F1X4I12_type,
+   MATCH_R2_FLUSHD, MASK_R2_FLUSHD, 0, address_offset_overflow},
+  {"flushda", "I(s)", "I(s),E", 2, 4, iw_F1X4I12_type,
+   MATCH_R2_FLUSHDA, MASK_R2_FLUSHDA, 0, address_offset_overflow},
+  {"flushi", "s", "s,E", 1, 4, iw_F3X6_type,
+   MATCH_R2_FLUSHI, MASK_R2_FLUSHI, 0, no_overflow},
+  {"flushp", "", "E", 0, 4, iw_F3X6_type,
+   MATCH_R2_FLUSHP, MASK_R2_FLUSHP, 0, no_overflow},
+  {"initd", "I(s)", "I(s),E", 2, 4, iw_F1X4I12_type,
+   MATCH_R2_INITD, MASK_R2_INITD, 0, address_offset_overflow},
+  {"initda", "I(s)", "I(s),E", 2, 4, iw_F1X4I12_type,
+   MATCH_R2_INITDA, MASK_R2_INITDA, 0, address_offset_overflow},
+  {"initi", "s", "s,E", 1, 4, iw_F3X6_type,
+   MATCH_R2_INITI, MASK_R2_INITI, 0, no_overflow},
+  {"insert", "t,s,j,k", "t,s,j,k,E", 4, 4, iw_F2X6L10_type,
+   MATCH_R2_INSERT, MASK_R2_INSERT, 0, no_overflow},
+  {"jmp", "s", "s,E", 1, 4, iw_F3X6_type,
+   MATCH_R2_JMP, MASK_R2_JMP, 0, no_overflow},
+  {"jmpi", "m", "m,E", 1, 4, iw_L26_type,
+   MATCH_R2_JMPI, MASK_R2_JMPI, 0, call_target_overflow},
+  {"jmpr.n", "s", "s,E", 1, 2, iw_F1X1_type,
+   MATCH_R2_JMPR_N, MASK_R2_JMPR_N, 0, no_overflow},
+  {"ldb", "t,i(s)", "t,i(s),E", 3, 4, iw_F2I16_type,
+   MATCH_R2_LDB, MASK_R2_LDB, 0, address_offset_overflow},
+  {"ldbio", "t,I(s)", "t,I(s),E", 3, 4, iw_F2X4I12_type,
+   MATCH_R2_LDBIO, MASK_R2_LDBIO, 0, signed_immed12_overflow},
+  {"ldbu", "t,i(s)", "t,i(s),E", 3, 4, iw_F2I16_type,
+   MATCH_R2_LDBU, MASK_R2_LDBU, 0, address_offset_overflow},
+  {"ldbuio", "t,I(s)", "t,I(s),E", 3, 4, iw_F2X4I12_type,
+   MATCH_R2_LDBUIO, MASK_R2_LDBUIO, 0, signed_immed12_overflow},
+  {"ldbu.n", "T,Y(S)", "T,Y(S),E", 3, 2, iw_T2I4_type,
+   MATCH_R2_LDBU_N, MASK_R2_LDBU_N, 0, address_offset_overflow},
+  {"ldex", "d,(s)", "d,(s),E", 2, 4, iw_F3X6_type,
+   MATCH_R2_LDEX, MASK_R2_LDEX, 0, no_overflow},
+  {"ldh", "t,i(s)", "t,i(s),E", 3, 4, iw_F2I16_type,
+   MATCH_R2_LDH, MASK_R2_LDH, 0, address_offset_overflow},
+  {"ldhio", "t,I(s)", "t,I(s),E", 3, 4, iw_F2X4I12_type,
+   MATCH_R2_LDHIO, MASK_R2_LDHIO, 0, signed_immed12_overflow},
+  {"ldhu", "t,i(s)", "t,i(s),E", 3, 4, iw_F2I16_type,
+   MATCH_R2_LDHU, MASK_R2_LDHU, 0, address_offset_overflow},
+  {"ldhuio", "t,I(s)", "t,I(s),E", 3, 4, iw_F2X4I12_type,
+   MATCH_R2_LDHUIO, MASK_R2_LDHUIO, 0, signed_immed12_overflow},
+  {"ldhu.n", "T,X(S)", "T,X(S),E", 3, 2, iw_T2I4_type,
+   MATCH_R2_LDHU_N, MASK_R2_LDHU_N, 0, address_offset_overflow},
+  {"ldsex", "d,(s)", "d,(s),E", 2, 4, iw_F3X6_type,
+   MATCH_R2_LDSEX, MASK_R2_LDSEX, 0, no_overflow},
+  {"ldw", "t,i(s)", "t,i(s),E", 3, 4, iw_F2I16_type,
+   MATCH_R2_LDW, MASK_R2_LDW, 0, address_offset_overflow},
+  {"ldwio", "t,I(s)", "t,I(s),E", 3, 4, iw_F2X4I12_type,
+   MATCH_R2_LDWIO, MASK_R2_LDWIO, 0, signed_immed12_overflow},
+  {"ldwm", "R,B", "R,B,E", 2, 4, iw_F1X4L17_type,
+   MATCH_R2_LDWM, MASK_R2_LDWM, 0, no_overflow},
+  {"ldw.n", "T,W(S)", "T,W(S),E", 3, 2, iw_T2I4_type,
+   MATCH_R2_LDW_N, MASK_R2_LDW_N, 0, address_offset_overflow},
+  {"ldwsp.n", "t,V(s)", "t,V(s),E", 3, 2, iw_F1I5_type,
+   MATCH_R2_LDWSP_N, MASK_R2_LDWSP_N, 0, address_offset_overflow},
+  {"merge", "t,s,j,k", "t,s,j,k,E", 4, 4, iw_F2X6L10_type,
+   MATCH_R2_MERGE, MASK_R2_MERGE, 0, no_overflow},
+  {"mov", "d,s", "d,s,E", 2, 4, iw_F3X6_type,
+   MATCH_R2_MOV, MASK_R2_MOV, NIOS2_INSN_MACRO_MOV, no_overflow},
+  {"mov.n", "d,s", "d,s,E", 2, 2, iw_F2_type,
+   MATCH_R2_MOV_N, MASK_R2_MOV_N, 0, no_overflow},
+  {"movi.n", "D,h", "D,h,E", 2, 2, iw_T1I7_type,
+   MATCH_R2_MOVI_N, MASK_R2_MOVI_N, 0, enumeration_overflow},
+  {"movhi", "t,u", "t,u,E", 2, 4, iw_F2I16_type,
+   MATCH_R2_MOVHI, MASK_R2_MOVHI,
+   NIOS2_INSN_MACRO_MOVI, unsigned_immed16_overflow},
+  {"movi", "t,i", "t,i,E", 2, 4, iw_F2I16_type,
+   MATCH_R2_MOVI, MASK_R2_MOVI, NIOS2_INSN_MACRO_MOVI, signed_immed16_overflow},
+  {"movia", "t,o", "t,o,E", 2, 4, iw_F2I16_type,
+   MATCH_R2_ORHI, MASK_R2_ORHI, NIOS2_INSN_MACRO_MOVIA, no_overflow},
+  {"movui", "t,u", "t,u,E", 2, 4, iw_F2I16_type,
+   MATCH_R2_MOVUI, MASK_R2_MOVUI,
+   NIOS2_INSN_MACRO_MOVI, unsigned_immed16_overflow},
+  {"mul", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_MUL, MASK_R2_MUL, 0, no_overflow},
+  {"muli", "t,s,i", "t,s,i,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_MULI, MASK_R2_MULI, 0, signed_immed16_overflow},
+  {"mulxss", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_MULXSS, MASK_R2_MULXSS, 0, no_overflow},
+  {"mulxsu", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_MULXSU, MASK_R2_MULXSU, 0, no_overflow},
+  {"mulxuu", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_MULXUU, MASK_R2_MULXUU, 0, no_overflow},
+  /* The encoding of the neg.n operands is backwards, not
+     the interpretation -- the first operand is still the
+     destination and the second the source.  */
+  {"neg.n", "S,D", "S,D,E", 2, 2, iw_T2X3_type,
+   MATCH_R2_NEG_N, MASK_R2_NEG_N, 0, no_overflow},
+  {"nextpc", "d", "d,E", 1, 4, iw_F3X6_type,
+   MATCH_R2_NEXTPC, MASK_R2_NEXTPC, 0, no_overflow},
+  {"nop", "", "E", 0, 4, iw_F3X6_type,
+   MATCH_R2_NOP, MASK_R2_NOP, NIOS2_INSN_MACRO_MOV, no_overflow},
+  {"nop.n", "", "E", 0, 2, iw_F2_type,
+   MATCH_R2_NOP_N, MASK_R2_NOP_N, NIOS2_INSN_MACRO_MOV, no_overflow},
+  {"nor", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_NOR, MASK_R2_NOR, 0, no_overflow},
+  {"not.n", "D,S", "D,S,E", 2, 2, iw_T2X3_type,
+   MATCH_R2_NOT_N, MASK_R2_NOT_N, 0, no_overflow},
+  {"or", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_OR, MASK_R2_OR, 0, no_overflow},
+  {"orhi", "t,s,u", "t,s,u,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_ORHI, MASK_R2_ORHI, 0, unsigned_immed16_overflow},
+  {"ori", "t,s,u", "t,s,u,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_ORI, MASK_R2_ORI, 0, unsigned_immed16_overflow},
+  {"or.n", "D,S,T", "D,S,T,E", 3, 2, iw_T2X3_type,
+   MATCH_R2_OR_N, MASK_R2_OR_N, 0, no_overflow},
+  {"pop.n", "R,W", "R,W,E", 2, 2, iw_L5I4X1_type,
+   MATCH_R2_POP_N, MASK_R2_POP_N, NIOS2_INSN_OPTARG, no_overflow},
+  {"push.n", "R,W", "R,W,E", 2, 2, iw_L5I4X1_type,
+   MATCH_R2_PUSH_N, MASK_R2_PUSH_N, NIOS2_INSN_OPTARG, no_overflow},
+  {"rdctl", "d,c", "d,c,E", 2, 4, iw_F3X6L5_type,
+   MATCH_R2_RDCTL, MASK_R2_RDCTL, 0, no_overflow},
+  {"rdprs", "t,s,I", "t,s,I,E", 3, 4, iw_F2X4I12_type,
+   MATCH_R2_RDPRS, MASK_R2_RDPRS, 0, signed_immed12_overflow},
+  {"ret", "", "E", 0, 4, iw_F3X6_type,
+   MATCH_R2_RET, MASK_R2_RET, 0, no_overflow},
+  {"ret.n", "", "E", 0, 2, iw_X2L5_type,
+   MATCH_R2_RET_N, MASK_R2_RET_N, 0, no_overflow},
+  {"rol", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_ROL, MASK_R2_ROL, 0, no_overflow},
+  {"roli", "d,s,j", "d,s,j,E", 3, 4, iw_F3X6L5_type,
+   MATCH_R2_ROLI, MASK_R2_ROLI, 0, unsigned_immed5_overflow},
+  {"ror", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_ROR, MASK_R2_ROR, 0, no_overflow},
+  {"sll", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_SLL, MASK_R2_SLL, 0, no_overflow},
+  {"slli", "d,s,j", "d,s,j,E", 3, 4, iw_F3X6L5_type,
+   MATCH_R2_SLLI, MASK_R2_SLLI, 0, unsigned_immed5_overflow},
+  {"sll.n", "D,S,T", "D,S,T,E", 3, 2, iw_T2X3_type,
+   MATCH_R2_SLL_N, MASK_R2_SLL_N, 0, no_overflow},
+  {"slli.n", "D,S,f", "D,S,f,E", 3, 2, iw_T2X1L3_type,
+   MATCH_R2_SLLI_N, MASK_R2_SLLI_N, 0, enumeration_overflow},
+  {"spaddi.n", "D,U", "D,U,E", 2, 2, iw_T1I7_type,
+   MATCH_R2_SPADDI_N, MASK_R2_SPADDI_N, 0, address_offset_overflow},
+  {"spdeci.n", "U", "U,E", 1, 2, iw_X1I7_type,
+   MATCH_R2_SPDECI_N, MASK_R2_SPDECI_N, 0, address_offset_overflow},
+  {"spinci.n", "U", "U,E", 1, 2, iw_X1I7_type,
+   MATCH_R2_SPINCI_N, MASK_R2_SPINCI_N, 0, address_offset_overflow},
+  {"sra", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_SRA, MASK_R2_SRA, 0, no_overflow},
+  {"srai", "d,s,j", "d,s,j,E", 3, 4, iw_F3X6L5_type,
+   MATCH_R2_SRAI, MASK_R2_SRAI, 0, unsigned_immed5_overflow},
+  {"srl", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_SRL, MASK_R2_SRL, 0, no_overflow},
+  {"srli", "d,s,j", "d,s,j,E", 3, 4, iw_F3X6L5_type,
+   MATCH_R2_SRLI, MASK_R2_SRLI, 0, unsigned_immed5_overflow},
+  {"srl.n", "D,S,T", "D,S,T,E", 3, 2, iw_T2X3_type,
+   MATCH_R2_SRL_N, MASK_R2_SRL_N, 0, no_overflow},
+  {"srli.n", "D,S,f", "D,S,f,E", 3, 2, iw_T2X1L3_type,
+   MATCH_R2_SRLI_N, MASK_R2_SRLI_N, 0, enumeration_overflow},
+  {"stb", "t,i(s)", "t,i(s),E", 3, 4, iw_F2I16_type,
+   MATCH_R2_STB, MASK_R2_STB, 0, address_offset_overflow},
+  {"stbio", "t,I(s)", "t,I(s),E", 3, 4, iw_F2X4I12_type,
+   MATCH_R2_STBIO, MASK_R2_STBIO, 0, signed_immed12_overflow},
+  {"stb.n", "T,Y(S)", "T,Y(S),E", 3, 2, iw_T2I4_type,
+   MATCH_R2_STB_N, MASK_R2_STB_N, 0, address_offset_overflow},
+  {"stbz.n", "t,M(S)", "t,M(S),E", 3, 2, iw_T1X1I6_type,
+   MATCH_R2_STBZ_N, MASK_R2_STBZ_N, 0, address_offset_overflow},
+  {"stex", "d,t,(s)", "d,t,(s),E", 3, 4, iw_F3X6_type,
+   MATCH_R2_STEX, MASK_R2_STEX, 0, no_overflow},
+  {"sth", "t,i(s)", "t,i(s),E", 3, 4, iw_F2I16_type,
+   MATCH_R2_STH, MASK_R2_STH, 0, address_offset_overflow},
+  {"sthio", "t,I(s)", "t,I(s),E", 3, 4, iw_F2X4I12_type,
+   MATCH_R2_STHIO, MASK_R2_STHIO, 0, signed_immed12_overflow},
+  {"sth.n", "T,X(S)", "T,X(S),E", 3, 2, iw_T2I4_type,
+   MATCH_R2_STH_N, MASK_R2_STH_N, 0, address_offset_overflow},
+  {"stsex", "d,t,(s)", "d,t,(s),E", 3, 4, iw_F3X6_type,
+   MATCH_R2_STSEX, MASK_R2_STSEX, 0, no_overflow},
+  {"stw", "t,i(s)", "t,i(s),E", 3, 4, iw_F2I16_type,
+   MATCH_R2_STW, MASK_R2_STW, 0, address_offset_overflow},
+  {"stwio", "t,I(s)", "t,I(s),E", 3, 4, iw_F2X4I12_type,
+   MATCH_R2_STWIO, MASK_R2_STWIO, 0, signed_immed12_overflow},
+  {"stwm", "R,B", "R,B,E", 2, 4, iw_F1X4L17_type,
+   MATCH_R2_STWM, MASK_R2_STWM, 0, no_overflow},
+  {"stwsp.n", "t,V(s)", "t,V(s),E", 3, 2, iw_F1I5_type,
+   MATCH_R2_STWSP_N, MASK_R2_STWSP_N, 0, address_offset_overflow},
+  {"stw.n", "T,W(S)", "T,W(S),E", 3, 2, iw_T2I4_type,
+   MATCH_R2_STW_N, MASK_R2_STW_N, 0, address_offset_overflow},
+  {"stwz.n", "t,N(S)", "t,N(S),E", 3, 2, iw_T1X1I6_type,
+   MATCH_R2_STWZ_N, MASK_R2_STWZ_N, 0, address_offset_overflow},
+  {"sub", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_SUB, MASK_R2_SUB, 0, no_overflow},
+  {"subi", "t,s,i", "t,s,i,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_SUBI, MASK_R2_SUBI, NIOS2_INSN_MACRO, signed_immed16_overflow},
+  {"sub.n", "D,S,T", "D,S,T,E", 3, 2, iw_T3X1_type,
+   MATCH_R2_SUB_N, MASK_R2_SUB_N, 0, no_overflow},
+  {"subi.n", "D,S,e", "D,S,e,E", 3, 2, iw_T2X1I3_type,
+   MATCH_R2_SUBI_N, MASK_R2_SUBI_N, 0, enumeration_overflow},
+  {"sync", "", "E", 0, 4, iw_F3X6_type,
+   MATCH_R2_SYNC, MASK_R2_SYNC, 0, no_overflow},
+  {"trap", "j", "j,E", 1, 4, iw_F3X6L5_type,
+   MATCH_R2_TRAP, MASK_R2_TRAP, NIOS2_INSN_OPTARG, no_overflow},
+  {"trap.n", "j", "j,E", 1, 2, iw_X2L5_type,
+   MATCH_R2_TRAP_N, MASK_R2_TRAP_N, NIOS2_INSN_OPTARG, no_overflow},
+  {"wrctl", "c,s", "c,s,E", 2, 4, iw_F3X6L5_type,
+   MATCH_R2_WRCTL, MASK_R2_WRCTL, 0, no_overflow},
+  {"wrpie", "d,s", "d,s,E", 2, 4, iw_F3X6L5_type,
+   MATCH_R2_WRPIE, MASK_R2_WRPIE, 0, no_overflow},
+  {"wrprs", "d,s", "d,s,E", 2, 4, iw_F3X6_type,
+   MATCH_R2_WRPRS, MASK_R2_WRPRS, 0, no_overflow},
+  {"xor", "d,s,t", "d,s,t,E", 3, 4, iw_F3X6_type,
+   MATCH_R2_XOR, MASK_R2_XOR, 0, no_overflow},
+  {"xorhi", "t,s,u", "t,s,u,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_XORHI, MASK_R2_XORHI, 0, unsigned_immed16_overflow},
+  {"xori", "t,s,u", "t,s,u,E", 3, 4, iw_F2I16_type,
+   MATCH_R2_XORI, MASK_R2_XORI, 0, unsigned_immed16_overflow},
+  {"xor.n", "D,S,T", "D,S,T,E", 3, 2, iw_T2X3_type,
+   MATCH_R2_XOR_N, MASK_R2_XOR_N, 0, no_overflow},
+};
+
+#define NIOS2_NUM_R2_OPCODES \
+       ((sizeof nios2_r2_opcodes) / (sizeof (nios2_r2_opcodes[0])))
+const int nios2_num_r2_opcodes = NIOS2_NUM_R2_OPCODES;
+
+/* Default to using the R1 instruction tables.  */
+struct nios2_opcode *nios2_opcodes = (struct nios2_opcode *) nios2_r1_opcodes;
+int nios2_num_opcodes = NIOS2_NUM_R1_OPCODES;
+#undef NIOS2_NUM_R1_OPCODES
+#undef NIOS2_NUM_R2_OPCODES
+
+/* Decodings for R2 asi.n (addi.n/subi.n) immediate values.  */
+unsigned int nios2_r2_asi_n_mappings[] =
+  {1, 2, 4, 8, 16, 32, 64, 128};
+const int nios2_num_r2_asi_n_mappings = 8;
+
+/* Decodings for R2 shi.n (slli.n/srli.n) immediate values.  */
+unsigned int nios2_r2_shi_n_mappings[] =
+  {1, 2, 3, 8, 12, 16, 24, 31};
+const int nios2_num_r2_shi_n_mappings = 8;
+
+/* Decodings for R2 andi.n immediate values.  */
+unsigned int nios2_r2_andi_n_mappings[] =
+  {1, 2, 3, 4, 8, 0xf, 0x10, 0x1f,
+   0x20, 0x3f, 0x7f, 0x80, 0xff, 0x7ff, 0xff00, 0xffff};
+const int nios2_num_r2_andi_n_mappings = 16;
+
+/* Decodings for R2 3-bit register fields.  */
+int nios2_r2_reg3_mappings[] =
+  {16, 17, 2, 3, 4, 5, 6, 7};
+const int nios2_num_r2_reg3_mappings = 8;
+
+/* Decodings for R2 push.n/pop.n REG_RANGE value list.  */
+unsigned long nios2_r2_reg_range_mappings[] = {
+  0x00010000,
+  0x00030000,
+  0x00070000,
+  0x000f0000,
+  0x001f0000,
+  0x003f0000,
+  0x007f0000,
+  0x00ff0000
+};
+const int nios2_num_r2_reg_range_mappings = 8;
+
+/*#include "sysdep.h"
+#include "dis-asm.h"
+#include "opcode/nios2.h"
+#include "libiberty.h"
+#include <string.h>
+#include <assert.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
+
+/* Default length of Nios II instruction in bytes.  */
+#define INSNLEN 4
+
+/* 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;
+
+/* Hash table size.  */
+#define OPCODE_HASH_SIZE (IW_R1_OP_UNSHIFTED_MASK + 1)
+
+/* Extract the opcode from an instruction word.  */
+static unsigned int
+nios2_r1_extract_opcode (unsigned int x)
+{
+  return GET_IW_R1_OP (x);
+}
+
+static unsigned int
+nios2_r2_extract_opcode (unsigned int x)
+{
+  return GET_IW_R2_OP (x);
+}
+
+/* We maintain separate hash tables for R1 and R2 opcodes, and pseudo-ops
+   are stored in a different table than regular instructions.  */
+
+typedef struct _nios2_disassembler_state
+{
+  const struct nios2_opcode *opcodes;
+  const int *num_opcodes;
+  unsigned int (*extract_opcode) (unsigned int);
+  nios2_opcode_hash *hash[OPCODE_HASH_SIZE];
+  nios2_opcode_hash *ps_hash[OPCODE_HASH_SIZE];
+  const struct nios2_opcode *nop;
+  bfd_boolean init;
+} nios2_disassembler_state;
+
+static nios2_disassembler_state
+nios2_r1_disassembler_state = {
+  nios2_r1_opcodes,
+  &nios2_num_r1_opcodes,
+  nios2_r1_extract_opcode,
+  {},
+  {},
+  NULL,
+  0
+};
+
+static nios2_disassembler_state
+nios2_r2_disassembler_state = {
+  nios2_r2_opcodes,
+  &nios2_num_r2_opcodes,
+  nios2_r2_extract_opcode,
+  {},
+  {},
+  NULL,
+  0
+};
+
+/* Function to initialize the opcode hash table.  */
+static void
+nios2_init_opcode_hash (nios2_disassembler_state *state)
+{
+  unsigned int i;
+  register const struct nios2_opcode *op;
+
+  for (i = 0; i < OPCODE_HASH_SIZE; i++)
+    for (op = state->opcodes; op < &state->opcodes[*(state->num_opcodes)]; op++)
+      {
+	nios2_opcode_hash *new_hash;
+	nios2_opcode_hash **bucket = NULL;
+
+	if ((op->pinfo & NIOS2_INSN_MACRO) == NIOS2_INSN_MACRO)
+	  {
+	    if (i == state->extract_opcode (op->match)
+		&& (op->pinfo & (NIOS2_INSN_MACRO_MOV | NIOS2_INSN_MACRO_MOVI)
+		    & 0x7fffffff))
+	      {
+		bucket = &(state->ps_hash[i]);
+		if (strcmp (op->name, "nop") == 0)
+		  state->nop = op;
+	      }
+	  }
+	else if (i == state->extract_opcode (op->match))
+	  bucket = &(state->hash[i]);
+
+	if (bucket)
+	  {
+	    new_hash =
+	      (nios2_opcode_hash *) malloc (sizeof (nios2_opcode_hash));
+	    if (new_hash == NULL)
+	      {
+		fprintf (stderr,
+			 "error allocating memory...broken disassembler\n");
+		abort ();
+	      }
+	    new_hash->opcode = op;
+	    new_hash->next = NULL;
+	    while (*bucket)
+	      bucket = &((*bucket)->next);
+	    *bucket = new_hash;
+	  }
+      }
+  state->init = 1;
+
+#ifdef DEBUG_HASHTABLE
+  for (i = 0; i < OPCODE_HASH_SIZE; ++i)
+    {
+      nios2_opcode_hash *tmp_hash = state->hash[i];
+      printf ("index: 0x%02X	ops: ", i);
+      while (tmp_hash != NULL)
+	{
+	  printf ("%s ", tmp_hash->opcode->name);
+	  tmp_hash = tmp_hash->next;
+	}
+      printf ("\n");
+    }
+
+  for (i = 0; i < OPCODE_HASH_SIZE; ++i)
+    {
+      nios2_opcode_hash *tmp_hash = state->ps_hash[i];
+      printf ("index: 0x%02X	ops: ", i);
+      while (tmp_hash != NULL)
+	{
+	  printf ("%s ", tmp_hash->opcode->name);
+	  tmp_hash = tmp_hash->next;
+	}
+      printf ("\n");
+    }
+#endif /* DEBUG_HASHTABLE */
+}
+
+/* Return a pointer to an nios2_opcode struct for a given instruction
+   word OPCODE for bfd machine MACH, or NULL if there is an error.  */
+const struct nios2_opcode *
+nios2_find_opcode_hash (unsigned long opcode, unsigned long mach)
+{
+  nios2_opcode_hash *entry;
+  nios2_disassembler_state *state;
+
+  /* Select the right instruction set, hash tables, and opcode accessor
+     for the mach variant.  */
+  if (mach == bfd_mach_nios2r2)
+    state = &nios2_r2_disassembler_state;
+  else
+    state = &nios2_r1_disassembler_state;
+
+  /* Build a hash table to shorten the search time.  */
+  if (!state->init)
+    nios2_init_opcode_hash (state);
+
+  /* Check for NOP first.  Both NOP and MOV are macros that expand into
+     an ADD instruction, and we always want to give priority to NOP.  */
+  if (state->nop->match == (opcode & state->nop->mask))
+    return state->nop;
+
+  /* First look in the pseudo-op hashtable.  */
+  for (entry = state->ps_hash[state->extract_opcode (opcode)];
+       entry; entry = entry->next)
+    if (entry->opcode->match == (opcode & entry->opcode->mask))
+      return entry->opcode;
+
+  /* Otherwise look in the main hashtable.  */
+  for (entry = state->hash[state->extract_opcode (opcode)];
+       entry; entry = entry->next)
+    if (entry->opcode->match == (opcode & entry->opcode->mask))
+      return entry->opcode;
+
+  return NULL;
+}
+
+/* There are 32 regular registers, 32 coprocessor registers,
+   and 32 control registers.  */
+#define NUMREGNAMES 32
+
+/* Return a pointer to the base of the coprocessor register name array.  */
+static struct nios2_reg *
+nios2_coprocessor_regs (void)
+{
+  static struct nios2_reg *cached = NULL;
+
+  if (!cached)
+    {
+      int i;
+      for (i = NUMREGNAMES; i < nios2_num_regs; i++)
+	if (!strcmp (nios2_regs[i].name, "c0"))
+	  {
+	    cached = nios2_regs + i;
+	    break;
+	  }
+      assert (cached);
+    }
+  return cached;
+}
+
+/* Return a pointer to the base of the control register name array.  */
+static struct nios2_reg *
+nios2_control_regs (void)
+{
+  static struct nios2_reg *cached = NULL;
+
+  if (!cached)
+    {
+      int i;
+      for (i = NUMREGNAMES; i < nios2_num_regs; i++)
+	if (!strcmp (nios2_regs[i].name, "status"))
+	  {
+	    cached = nios2_regs + i;
+	    break;
+	  }
+      assert (cached);
+    }
+  return cached;
+}
+
+/* Helper routine to report internal errors.  */
+static void
+bad_opcode (const struct nios2_opcode *op)
+{
+  fprintf (stderr, "Internal error: broken opcode descriptor for `%s %s'\n",
+	   op->name, op->args);
+  abort ();
+}
+
+/* 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.  */
+static int
+nios2_print_insn_arg (const char *argptr,
+		      unsigned long opcode, bfd_vma address,
+		      disassemble_info *info,
+		      const struct nios2_opcode *op)
+{
+  unsigned long i = 0;
+  struct nios2_reg *reg_base;
+
+  switch (*argptr)
+    {
+    case ',':
+    case '(':
+    case ')':
+      (*info->fprintf_func) (info->stream, "%c", *argptr);
+      break;
+
+    case 'c':
+      /* Control register index.  */
+      switch (op->format)
+	{
+	case iw_r_type:
+	  i = GET_IW_R_IMM5 (opcode);
+	  break;
+	case iw_F3X6L5_type:
+	  i = GET_IW_F3X6L5_IMM5 (opcode);
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      reg_base = nios2_control_regs ();
+      (*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
+      break;
+
+    case 'd':
+      reg_base = nios2_regs;
+      switch (op->format)
+	{
+	case iw_r_type:
+	  i = GET_IW_R_C (opcode);
+	  break;
+	case iw_custom_type:
+	  i = GET_IW_CUSTOM_C (opcode);
+	  if (GET_IW_CUSTOM_READC (opcode) == 0)
+	    reg_base = nios2_coprocessor_regs ();
+	  break;
+	case iw_F3X6L5_type:
+	case iw_F3X6_type:
+	  i = GET_IW_F3X6L5_C (opcode);
+	  break;
+	case iw_F3X8_type:
+	  i = GET_IW_F3X8_C (opcode);
+	  if (GET_IW_F3X8_READC (opcode) == 0)
+	    reg_base = nios2_coprocessor_regs ();
+	  break;
+	case iw_F2_type:
+	  i = GET_IW_F2_B (opcode);
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      if (i < NUMREGNAMES)
+	(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
+      else
+	(*info->fprintf_func) (info->stream, "unknown");
+      break;
+
+    case 's':
+      reg_base = nios2_regs;
+      switch (op->format)
+	{
+	case iw_r_type:
+	  i = GET_IW_R_A (opcode);
+	  break;
+	case iw_i_type:
+	  i = GET_IW_I_A (opcode);
+	  break;
+	case iw_custom_type:
+	  i = GET_IW_CUSTOM_A (opcode);
+	  if (GET_IW_CUSTOM_READA (opcode) == 0)
+	    reg_base = nios2_coprocessor_regs ();
+	  break;
+	case iw_F2I16_type:
+	  i = GET_IW_F2I16_A (opcode);
+	  break;
+	case iw_F2X4I12_type:
+	  i = GET_IW_F2X4I12_A (opcode);
+	  break;
+	case iw_F1X4I12_type:
+	  i = GET_IW_F1X4I12_A (opcode);
+	  break;
+	case iw_F1X4L17_type:
+	  i = GET_IW_F1X4L17_A (opcode);
+	  break;
+	case iw_F3X6L5_type:
+	case iw_F3X6_type:
+	  i = GET_IW_F3X6L5_A (opcode);
+	  break;
+	case iw_F2X6L10_type:
+	  i = GET_IW_F2X6L10_A (opcode);
+	  break;
+	case iw_F3X8_type:
+	  i = GET_IW_F3X8_A (opcode);
+	  if (GET_IW_F3X8_READA (opcode) == 0)
+	    reg_base = nios2_coprocessor_regs ();
+	  break;
+	case iw_F1X1_type:
+	  i = GET_IW_F1X1_A (opcode);
+	  break;
+	case iw_F1I5_type:
+	  i = 27;   /* Implicit stack pointer reference.  */
+	  break;
+	case iw_F2_type:
+	  i = GET_IW_F2_A (opcode);
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      if (i < NUMREGNAMES)
+	(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
+      else
+	(*info->fprintf_func) (info->stream, "unknown");
+      break;
+
+    case 't':
+      reg_base = nios2_regs;
+      switch (op->format)
+	{
+	case iw_r_type:
+	  i = GET_IW_R_B (opcode);
+	  break;
+	case iw_i_type:
+	  i = GET_IW_I_B (opcode);
+	  break;
+	case iw_custom_type:
+	  i = GET_IW_CUSTOM_B (opcode);
+	  if (GET_IW_CUSTOM_READB (opcode) == 0)
+	    reg_base = nios2_coprocessor_regs ();
+	  break;
+	case iw_F2I16_type:
+	  i = GET_IW_F2I16_B (opcode);
+	  break;
+	case iw_F2X4I12_type:
+	  i = GET_IW_F2X4I12_B (opcode);
+	  break;
+	case iw_F3X6L5_type:
+	case iw_F3X6_type:
+	  i = GET_IW_F3X6L5_B (opcode);
+	  break;
+	case iw_F2X6L10_type:
+	  i = GET_IW_F2X6L10_B (opcode);
+	  break;
+	case iw_F3X8_type:
+	  i = GET_IW_F3X8_B (opcode);
+	  if (GET_IW_F3X8_READB (opcode) == 0)
+	    reg_base = nios2_coprocessor_regs ();
+	  break;
+	case iw_F1I5_type:
+	  i = GET_IW_F1I5_B (opcode);
+	  break;
+	case iw_F2_type:
+	  i = GET_IW_F2_B (opcode);
+	  break;
+	case iw_T1X1I6_type:
+	  i = 0;
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      if (i < NUMREGNAMES)
+	(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
+      else
+	(*info->fprintf_func) (info->stream, "unknown");
+      break;
+
+    case 'D':
+      switch (op->format)
+	{
+	case iw_T1I7_type:
+	  i = GET_IW_T1I7_A3 (opcode);
+	  break;
+	case iw_T2X1L3_type:
+	  i = GET_IW_T2X1L3_B3 (opcode);
+	  break;
+	case iw_T2X1I3_type:
+	  i = GET_IW_T2X1I3_B3 (opcode);
+	  break;
+	case iw_T3X1_type:
+	  i = GET_IW_T3X1_C3 (opcode);
+	  break;
+	case iw_T2X3_type:
+	  if (op->num_args == 3)
+	    i = GET_IW_T2X3_A3 (opcode);
+	  else
+	    i = GET_IW_T2X3_B3 (opcode);
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      i = nios2_r2_reg3_mappings[i];
+      (*info->fprintf_func) (info->stream, "%s", nios2_regs[i].name);
+      break;
+
+    case 'M':
+      /* 6-bit unsigned immediate with no shift.  */
+      switch (op->format)
+	{
+	case iw_T1X1I6_type:
+	  i = GET_IW_T1X1I6_IMM6 (opcode);
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%ld", i);
+      break;
+
+    case 'N':
+      /* 6-bit unsigned immediate with 2-bit shift.  */
+      switch (op->format)
+	{
+	case iw_T1X1I6_type:
+	  i = GET_IW_T1X1I6_IMM6 (opcode) << 2;
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%ld", i);
+      break;
+
+    case 'S':
+      switch (op->format)
+	{
+	case iw_T1I7_type:
+	  i = GET_IW_T1I7_A3 (opcode);
+	  break;
+	case iw_T2I4_type:
+	  i = GET_IW_T2I4_A3 (opcode);
+	  break;
+	case iw_T2X1L3_type:
+	  i = GET_IW_T2X1L3_A3 (opcode);
+	  break;
+	case iw_T2X1I3_type:
+	  i = GET_IW_T2X1I3_A3 (opcode);
+	  break;
+	case iw_T3X1_type:
+	  i = GET_IW_T3X1_A3 (opcode);
+	  break;
+	case iw_T2X3_type:
+	  i = GET_IW_T2X3_A3 (opcode);
+	  break;
+	case iw_T1X1I6_type:
+	  i = GET_IW_T1X1I6_A3 (opcode);
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      i = nios2_r2_reg3_mappings[i];
+      (*info->fprintf_func) (info->stream, "%s", nios2_regs[i].name);
+      break;
+
+    case 'T':
+      switch (op->format)
+	{
+	case iw_T2I4_type:
+	  i = GET_IW_T2I4_B3 (opcode);
+	  break;
+	case iw_T3X1_type:
+	  i = GET_IW_T3X1_B3 (opcode);
+	  break;
+	case iw_T2X3_type:
+	  i = GET_IW_T2X3_B3 (opcode);
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      i = nios2_r2_reg3_mappings[i];
+      (*info->fprintf_func) (info->stream, "%s", nios2_regs[i].name);
+      break;
+
+    case 'i':
+      /* 16-bit signed immediate.  */
+      switch (op->format)
+	{
+	case iw_i_type:
+	  i = (signed) (GET_IW_I_IMM16 (opcode) << 16) >> 16;
+	  break;
+	case iw_F2I16_type:
+	  i = (signed) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16;
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%ld", i);
+      break;
+
+    case 'I':
+      /* 12-bit signed immediate.  */
+      switch (op->format)
+	{
+	case iw_F2X4I12_type:
+	  i = (signed) (GET_IW_F2X4I12_IMM12 (opcode) << 20) >> 20;
+	  break;
+	case iw_F1X4I12_type:
+	  i = (signed) (GET_IW_F1X4I12_IMM12 (opcode) << 20) >> 20;
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%ld", i);
+      break;
+
+    case 'u':
+      /* 16-bit unsigned immediate.  */
+      switch (op->format)
+	{
+	case iw_i_type:
+	  i = GET_IW_I_IMM16 (opcode);
+	  break;
+	case iw_F2I16_type:
+	  i = GET_IW_F2I16_IMM16 (opcode);
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%ld", i);
+      break;
+
+    case 'U':
+      /* 7-bit unsigned immediate with 2-bit shift.  */
+      switch (op->format)
+	{
+	case iw_T1I7_type:
+	  i = GET_IW_T1I7_IMM7 (opcode) << 2;
+	  break;
+	case iw_X1I7_type:
+	  i = GET_IW_X1I7_IMM7 (opcode) << 2;
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%ld", i);
+      break;
+
+    case 'V':
+      /* 5-bit unsigned immediate with 2-bit shift.  */
+      switch (op->format)
+	{
+	case iw_F1I5_type:
+	  i = GET_IW_F1I5_IMM5 (opcode) << 2;
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%ld", i);
+      break;
+
+    case 'W':
+      /* 4-bit unsigned immediate with 2-bit shift.  */
+      switch (op->format)
+	{
+	case iw_T2I4_type:
+	  i = GET_IW_T2I4_IMM4 (opcode) << 2;
+	  break;
+	case iw_L5I4X1_type:
+	  i = GET_IW_L5I4X1_IMM4 (opcode) << 2;
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%ld", i);
+      break;
+
+    case 'X':
+      /* 4-bit unsigned immediate with 1-bit shift.  */
+      switch (op->format)
+	{
+	case iw_T2I4_type:
+	  i = GET_IW_T2I4_IMM4 (opcode) << 1;
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%ld", i);
+      break;
+
+    case 'Y':
+      /* 4-bit unsigned immediate without shift.  */
+      switch (op->format)
+	{
+	case iw_T2I4_type:
+	  i = GET_IW_T2I4_IMM4 (opcode);
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%ld", i);
+      break;
+
+    case 'o':
+      /* 16-bit signed immediate address offset.  */
+      switch (op->format)
+	{
+	case iw_i_type:
+	  i = (signed) (GET_IW_I_IMM16 (opcode) << 16) >> 16;
+	  break;
+	case iw_F2I16_type:
+	  i = (signed) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16;
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      address = address + 4 + i;
+      (*info->print_address_func) (address, info);
+      break;
+
+    case 'O':
+      /* 10-bit signed address offset with 1-bit shift.  */
+      switch (op->format)
+	{
+	case iw_I10_type:
+	  i = (signed) (GET_IW_I10_IMM10 (opcode) << 22) >> 21;
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      address = address + 2 + i;
+      (*info->print_address_func) (address, info);
+      break;
+
+    case 'P':
+      /* 7-bit signed address offset with 1-bit shift.  */
+      switch (op->format)
+	{
+	case iw_T1I7_type:
+	  i = (signed) (GET_IW_T1I7_IMM7 (opcode) << 25) >> 24;
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      address = address + 2 + i;
+      (*info->print_address_func) (address, info);
+      break;
+
+    case 'j':
+      /* 5-bit unsigned immediate.  */
+      switch (op->format)
+	{
+	case iw_r_type:
+	  i = GET_IW_R_IMM5 (opcode);
+	  break;
+	case iw_F3X6L5_type:
+	  i = GET_IW_F3X6L5_IMM5 (opcode);
+	  break;
+	case iw_F2X6L10_type:
+	  i = GET_IW_F2X6L10_MSB (opcode);
+	  break;
+	case iw_X2L5_type:
+	  i = GET_IW_X2L5_IMM5 (opcode);
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%ld", i);
+      break;
+
+    case 'k':
+      /* Second 5-bit unsigned immediate field.  */
+      switch (op->format)
+	{
+	case iw_F2X6L10_type:
+	  i = GET_IW_F2X6L10_LSB (opcode);
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%ld", i);
+      break;
+
+    case 'l':
+      /* 8-bit unsigned immediate.  */
+      switch (op->format)
+	{
+	case iw_custom_type:
+	  i = GET_IW_CUSTOM_N (opcode);
+	  break;
+	case iw_F3X8_type:
+	  i = GET_IW_F3X8_N (opcode);
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%lu", i);
+      break;
+
+    case 'm':
+      /* 26-bit unsigned immediate.  */
+      switch (op->format)
+	{
+	case iw_j_type:
+	  i = GET_IW_J_IMM26 (opcode);
+	  break;
+	case iw_L26_type:
+	  i = GET_IW_L26_IMM26 (opcode);
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      /* This translates to an address because it's only used in call
+	 instructions.  */
+      address = (address & 0xf0000000) | (i << 2);
+      (*info->print_address_func) (address, info);
+      break;
+
+    case 'e':
+      /* Encoded enumeration for addi.n/subi.n.  */
+      switch (op->format)
+	{
+	case iw_T2X1I3_type:
+	  i = nios2_r2_asi_n_mappings[GET_IW_T2X1I3_IMM3 (opcode)];
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%lu", i);
+      break;
+
+    case 'f':
+      /* Encoded enumeration for slli.n/srli.n.  */
+      switch (op->format)
+	{
+	case iw_T2X1L3_type:
+	  i = nios2_r2_shi_n_mappings[GET_IW_T2X1I3_IMM3 (opcode)];
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%lu", i);
+      break;
+
+    case 'g':
+      /* Encoded enumeration for andi.n.  */
+      switch (op->format)
+	{
+	case iw_T2I4_type:
+	  i = nios2_r2_andi_n_mappings[GET_IW_T2I4_IMM4 (opcode)];
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%lu", i);
+      break;
+
+    case 'h':
+      /* Encoded enumeration for movi.n.  */
+      switch (op->format)
+	{
+	case iw_T1I7_type:
+	  i = GET_IW_T1I7_IMM7 (opcode);
+	  if (i == 125)
+	    i = 0xff;
+	  else if (i == 126)
+	    i = -2;
+	  else if (i == 127)
+	    i = -1;
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      (*info->fprintf_func) (info->stream, "%ld", i);
+      break;
+
+    case 'R':
+      {
+	unsigned long reglist = 0;
+	int dir = 1;
+	int k, t;
+
+	switch (op->format)
+	  {
+	  case iw_F1X4L17_type:
+	    /* Encoding for ldwm/stwm.  */
+	    i = GET_IW_F1X4L17_REGMASK (opcode);
+	    if (GET_IW_F1X4L17_RS (opcode))
+	      {
+		reglist = ((i << 14) & 0x00ffc000);
+		if (i & (1 << 10))
+		  reglist |= (1 << 28);
+		if (i & (1 << 11))
+		  reglist |= (1 << 31);
+	      }
+	    else
+	      reglist = i << 2;
+	    dir = GET_IW_F1X4L17_REGMASK (opcode) ? 1 : -1;
+	    break;
+
+	  case iw_L5I4X1_type:
+	    /* Encoding for push.n/pop.n.  */
+	    reglist |= (1 << 31);
+	    if (GET_IW_L5I4X1_FP (opcode))
+	      reglist |= (1 << 28);
+	    if (GET_IW_L5I4X1_CS (opcode))
+	      {
+		int val = GET_IW_L5I4X1_REGRANGE (opcode);
+		reglist |= nios2_r2_reg_range_mappings[val];
+	      }
+	    dir = (op->match == MATCH_R2_POP_N ? 1 : -1);
+	    break;
+
+	  default:
+	    bad_opcode (op);
+	  }
+
+	t = 0;
+	(*info->fprintf_func) (info->stream, "{");
+	for (k = (dir == 1 ? 0 : 31);
+	     (dir == 1 && k < 32) || (dir == -1 && k >= 0);
+	     k += dir)
+	  if (reglist & (1 << k))
+	    {
+	      if (t)
+		(*info->fprintf_func) (info->stream, ",");
+	      else
+		t++;
+	      (*info->fprintf_func) (info->stream, "%s", nios2_regs[k].name);
+	    }
+	(*info->fprintf_func) (info->stream, "}");
+	break;
+      }
+
+    case 'B':
+      /* Base register and options for ldwm/stwm.  */
+      switch (op->format)
+	{
+	case iw_F1X4L17_type:
+	  if (GET_IW_F1X4L17_ID (opcode) == 0)
+	    (*info->fprintf_func) (info->stream, "--");
+
+	  i = GET_IW_F1X4I12_A (opcode);
+	  (*info->fprintf_func) (info->stream, "(%s)",
+				 nios2_builtin_regs[i].name);
+
+	  if (GET_IW_F1X4L17_ID (opcode))
+	    (*info->fprintf_func) (info->stream, "++");
+	  if (GET_IW_F1X4L17_WB (opcode))
+	    (*info->fprintf_func) (info->stream, ",writeback");
+	  if (GET_IW_F1X4L17_PC (opcode))
+	    (*info->fprintf_func) (info->stream, ",ret");
+	  break;
+	default:
+	  bad_opcode (op);
+	}
+      break;
+
+    default:
+      (*info->fprintf_func) (info->stream, "unknown");
+      break;
+    }
+  return 0;
+}
+
+/* nios2_disassemble does all the work of disassembling a Nios II
+   instruction opcode.  */
+static int
+nios2_disassemble (bfd_vma address, unsigned long opcode,
+		   disassemble_info *info)
+{
+  const struct nios2_opcode *op;
+
+  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, info->mach);
+
+  if (op != NULL)
+    {
+      const char *argstr = op->args;
+      (*info->fprintf_func) (info->stream, "%s", op->name);
+      if (argstr != NULL && *argstr != '\0')
+	{
+	  (*info->fprintf_func) (info->stream, "\t");
+	  while (*argstr != '\0')
+	    {
+	      nios2_print_insn_arg (argstr, opcode, address, info, op);
+	      ++argstr;
+	    }
+	}
+      /* Tell the caller how far to advance the program counter.  */
+      info->bytes_per_chunk = op->size;
+      return op->size;
+    }
+  else
+    {
+      /* Handle undefined instructions.  */
+      info->insn_type = dis_noninsn;
+      (*info->fprintf_func) (info->stream, "0x%lx", opcode);
+      return INSNLEN;
+    }
+}
+
+
+/* print_insn_nios2 is the main disassemble function for Nios II.
+   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 Nios II. 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)
+{
+  bfd_byte buffer[INSNLEN];
+  int status;
+
+  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);
+      return nios2_disassemble (address, insn, info);
+    }
+
+  /* We might have a 16-bit R2 instruction at the end of memory.  Try that.  */
+  if (info->mach == bfd_mach_nios2r2)
+    {
+      status = (*info->read_memory_func) (address, buffer, 2, info);
+      if (status == 0)
+	{
+	  unsigned long insn;
+	  if (endianness == BFD_ENDIAN_BIG)
+	    insn = (unsigned long) bfd_getb16 (buffer);
+	  else
+	    insn = (unsigned long) bfd_getl16 (buffer);
+	  return nios2_disassemble (address, insn, info);
+	}
+    }
+
+  /* If we got here, we couldn't read anything.  */
+  (*info->memory_error_func) (status, address, info);
+  return -1;
+}
+
+/* These two functions are the main entry points, accessed from
+   disassemble.c.  */
+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);
+}
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index 8a3488c..0435b8c 100644
--- a/include/disas/bfd.h
+++ b/include/disas/bfd.h
@@ -222,6 +222,10 @@ enum bfd_architecture
   bfd_arch_ia64,      /* HP/Intel ia64 */
 #define bfd_mach_ia64_elf64    64
 #define bfd_mach_ia64_elf32    32
+  bfd_arch_nios2,	/* Nios II */
+#define bfd_mach_nios2          0
+#define bfd_mach_nios2r1        1
+#define bfd_mach_nios2r2        2
   bfd_arch_lm32,       /* Lattice Mico32 */
 #define bfd_mach_lm32 1
   bfd_arch_last
@@ -415,6 +419,8 @@ int print_insn_crisv10          (bfd_vma, disassemble_info*);
 int print_insn_microblaze       (bfd_vma, disassemble_info*);
 int print_insn_ia64             (bfd_vma, disassemble_info*);
 int print_insn_lm32             (bfd_vma, disassemble_info*);
+int print_insn_big_nios2        (bfd_vma, disassemble_info*);
+int print_insn_little_nios2     (bfd_vma, disassemble_info*);
 
 #if 0
 /* Fetch the disassembler for a given BFD, if that support is available.  */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support
  2016-09-27 23:30 [Qemu-devel] [PATCH V2 1/7] nios2: Add disas entries Marek Vasut
@ 2016-09-27 23:30 ` Marek Vasut
  2016-09-29  1:05   ` Richard Henderson
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 3/7] nios2: Add usermode binaries emulation Marek Vasut
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2016-09-27 23:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Chris Wulff, Marek Vasut, Jeff Da Silva, Ley Foon Tan,
	Sandra Loosemore, Yves Vandervennet

From: Chris Wulff <crwulff@gmail.com>

Add support for emulating Altera NiosII R1 architecture into qemu.
This patch is based on previous work by Chris Wulff from 2012 and
updated to latest mainline QEMU.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Chris Wulff <crwulff@gmail.com>
Cc: Jeff Da Silva <jdasilva@altera.com>
Cc: Ley Foon Tan <lftan@altera.com>
Cc: Sandra Loosemore <sandra@codesourcery.com>
Cc: Yves Vandervennet <yvanderv@altera.com>
---
 hw/nios2/cpu_pic.c         |   70 +++
 target-nios2/Makefile.objs |    4 +
 target-nios2/cpu.c         |  229 +++++++
 target-nios2/cpu.h         |  267 +++++++++
 target-nios2/helper.c      |  304 ++++++++++
 target-nios2/helper.h      |   41 ++
 target-nios2/instruction.c | 1427 ++++++++++++++++++++++++++++++++++++++++++++
 target-nios2/instruction.h |  279 +++++++++
 target-nios2/machine.c     |   38 ++
 target-nios2/mmu.c         |  292 +++++++++
 target-nios2/mmu.h         |   54 ++
 target-nios2/monitor.c     |   35 ++
 target-nios2/op_helper.c   |   86 +++
 target-nios2/translate.c   |  242 ++++++++
 14 files changed, 3368 insertions(+)
 create mode 100644 hw/nios2/cpu_pic.c
 create mode 100644 target-nios2/Makefile.objs
 create mode 100644 target-nios2/cpu.c
 create mode 100644 target-nios2/cpu.h
 create mode 100644 target-nios2/helper.c
 create mode 100644 target-nios2/helper.h
 create mode 100644 target-nios2/instruction.c
 create mode 100644 target-nios2/instruction.h
 create mode 100644 target-nios2/machine.c
 create mode 100644 target-nios2/mmu.c
 create mode 100644 target-nios2/mmu.h
 create mode 100644 target-nios2/monitor.c
 create mode 100644 target-nios2/op_helper.c
 create mode 100644 target-nios2/translate.c

diff --git a/hw/nios2/cpu_pic.c b/hw/nios2/cpu_pic.c
new file mode 100644
index 0000000..0f95987
--- /dev/null
+++ b/hw/nios2/cpu_pic.c
@@ -0,0 +1,70 @@
+/*
+ * Altera Nios2 CPU PIC
+ *
+ * Copyright (c) 2016 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+
+#include "qemu/config-file.h"
+
+#include "boot.h"
+
+static void nios2_pic_cpu_handler(void *opaque, int irq, int level)
+{
+    Nios2CPU *cpu = opaque;
+    CPUNios2State *env = &cpu->env;
+    CPUState *cs = CPU(cpu);
+    int type = irq ? CPU_INTERRUPT_NMI : CPU_INTERRUPT_HARD;
+
+    if (type == CPU_INTERRUPT_HARD) {
+        env->irq_pending = level;
+
+        if (level && (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
+            env->irq_pending = 0;
+            cpu_interrupt(cs, type);
+        } else if (!level) {
+            env->irq_pending = 0;
+            cpu_reset_interrupt(cs, type);
+        }
+    } else {
+        if (level) {
+            cpu_interrupt(cs, type);
+        } else {
+            cpu_reset_interrupt(cs, type);
+        }
+    }
+}
+
+void nios2_check_interrupts(CPUNios2State *env)
+{
+    Nios2CPU *cpu = nios2_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
+
+    if (env->irq_pending) {
+        env->irq_pending = 0;
+        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+    }
+}
+
+qemu_irq *nios2_cpu_pic_init(Nios2CPU *cpu)
+{
+    return qemu_allocate_irqs(nios2_pic_cpu_handler, cpu, 2);
+}
diff --git a/target-nios2/Makefile.objs b/target-nios2/Makefile.objs
new file mode 100644
index 0000000..ea6a528
--- /dev/null
+++ b/target-nios2/Makefile.objs
@@ -0,0 +1,4 @@
+obj-y += translate.o op_helper.o helper.o cpu.o mmu.o instruction.o
+obj-$(CONFIG_SOFTMMU) += monitor.o
+
+$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target-nios2/cpu.c b/target-nios2/cpu.c
new file mode 100644
index 0000000..5b4a2f6
--- /dev/null
+++ b/target-nios2/cpu.c
@@ -0,0 +1,229 @@
+/*
+ * QEMU Nios II CPU
+ *
+ * Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "exec/log.h"
+#include "exec/gdbstub.h"
+#include "hw/qdev-properties.h"
+
+static void nios2_cpu_set_pc(CPUState *cs, vaddr value)
+{
+    Nios2CPU *cpu = NIOS2_CPU(cs);
+    CPUNios2State *env = &cpu->env;
+
+    env->regs[R_PC] = value;
+}
+
+static bool nios2_cpu_has_work(CPUState *cs)
+{
+    return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
+}
+
+/* CPUClass::reset() */
+static void nios2_cpu_reset(CPUState *cs)
+{
+    Nios2CPU *cpu = NIOS2_CPU(cs);
+    Nios2CPUClass *ncc = NIOS2_CPU_GET_CLASS(cpu);
+    CPUNios2State *env = &cpu->env;
+
+    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+        qemu_log("CPU Reset (CPU %d)\n", cs->cpu_index);
+        log_cpu_state(cs, 0);
+    }
+
+    ncc->parent_reset(cs);
+
+    tlb_flush(cs, 1);
+
+    memset(env->regs, 0, sizeof(uint32_t) * NUM_CORE_REGS);
+    env->regs[R_PC] = env->reset_addr;
+
+#if defined(CONFIG_USER_ONLY)
+    /* Start in user mode with interrupts enabled. */
+    env->regs[CR_STATUS] = CR_STATUS_U | CR_STATUS_PIE;
+#endif
+}
+
+static void nios2_cpu_initfn(Object *obj)
+{
+    CPUState *cs = CPU(obj);
+    Nios2CPU *cpu = NIOS2_CPU(obj);
+    CPUNios2State *env = &cpu->env;
+    static bool tcg_initialized;
+
+    cpu->mmu_present = true;
+    cs->env_ptr = env;
+    cpu_exec_init(cs, &error_abort);
+
+#if !defined(CONFIG_USER_ONLY)
+    mmu_init(&env->mmu);
+#endif
+
+    if (tcg_enabled() && !tcg_initialized) {
+        tcg_initialized = true;
+        nios2_tcg_init();
+    }
+}
+
+Nios2CPU *cpu_nios2_init(const char *cpu_model)
+{
+    Nios2CPU *cpu = NIOS2_CPU(object_new(TYPE_NIOS2_CPU));
+
+    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
+
+    return cpu;
+}
+
+static void nios2_cpu_realizefn(DeviceState *dev, Error **errp)
+{
+    CPUState *cs = CPU(dev);
+    Nios2CPUClass *ncc = NIOS2_CPU_GET_CLASS(dev);
+
+    qemu_init_vcpu(cs);
+    cpu_reset(cs);
+
+    ncc->parent_realize(dev, errp);
+}
+
+static bool nios2_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+    Nios2CPU *cpu = NIOS2_CPU(cs);
+    CPUNios2State *env = &cpu->env;
+
+    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
+        (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
+        cs->exception_index = EXCP_IRQ;
+        nios2_cpu_do_interrupt(cs);
+        return true;
+    }
+    return false;
+}
+
+
+static void nios2_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
+{
+    /* NOTE: NiosII R2 is not supported yet. */
+    info->mach = bfd_arch_nios2;
+#ifdef TARGET_WORDS_BIGENDIAN
+    info->print_insn = print_insn_big_nios2;
+#else
+    info->print_insn = print_insn_little_nios2;
+#endif
+}
+
+static int nios2_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    Nios2CPU *cpu = NIOS2_CPU(cs);
+    CPUClass *cc = CPU_GET_CLASS(cs);
+    CPUNios2State *env = &cpu->env;
+
+    if (n > cc->gdb_num_core_regs)
+        return 0;
+
+    if (n < 32)		/* GP regs */
+        return gdb_get_reg32(mem_buf, env->regs[n]);
+    else if (n == 32)	/* PC */
+        return gdb_get_reg32(mem_buf, env->regs[R_PC]);
+    else if (n < 49)	/* Status regs */
+        return gdb_get_reg32(mem_buf, env->regs[n - 1]);
+    /* Invalid regs */
+    return 0;
+}
+
+static int nios2_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    Nios2CPU *cpu = NIOS2_CPU(cs);
+    CPUClass *cc = CPU_GET_CLASS(cs);
+    CPUNios2State *env = &cpu->env;
+
+    if (n > cc->gdb_num_core_regs)
+        return 0;
+
+    if (n < 32)		/* GP regs */
+        env->regs[n] = ldl_p(mem_buf);
+    else if (n == 32)	/* PC */
+        env->regs[R_PC] = ldl_p(mem_buf);
+    else if (n < 49)	/* Status regs */
+        env->regs[n - 1] = ldl_p(mem_buf);
+
+    return 4;
+}
+
+static Property nios2_properties[] = {
+    DEFINE_PROP_BOOL("mmu_present", Nios2CPU, mmu_present, true),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+
+static void nios2_cpu_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
+    Nios2CPUClass *ncc = NIOS2_CPU_CLASS(oc);
+
+    ncc->parent_realize = dc->realize;
+    dc->realize = nios2_cpu_realizefn;
+    dc->props = nios2_properties;
+    ncc->parent_reset = cc->reset;
+    cc->reset = nios2_cpu_reset;
+
+//FIXME    cc->class_by_name = nios2_cpu_class_by_name;
+    cc->has_work = nios2_cpu_has_work;
+    cc->do_interrupt = nios2_cpu_do_interrupt;
+    cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt;
+    cc->dump_state = nios2_cpu_dump_state;
+    cc->set_pc = nios2_cpu_set_pc;
+    cc->disas_set_info = nios2_cpu_disas_set_info;
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = nios2_cpu_handle_mmu_fault;
+#else
+    cc->get_phys_page_debug = nios2_cpu_get_phys_page_debug;
+/* FIXME *///    cc->do_unassigned_access = nios2_cpu_unassigned_access;
+#endif
+    cc->gdb_read_register = nios2_cpu_gdb_read_register;
+    cc->gdb_write_register = nios2_cpu_gdb_write_register;
+    cc->gdb_num_core_regs = 49;
+
+    /*
+     * Reason: nios2_cpu_initfn() calls cpu_exec_init(), which saves
+     * the object in cpus -> dangling pointer after final
+     * object_unref().
+     */
+    dc->cannot_destroy_with_object_finalize_yet = true;
+}
+
+static const TypeInfo nios2_cpu_type_info = {
+    .name = TYPE_NIOS2_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(Nios2CPU),
+    .instance_init = nios2_cpu_initfn,
+    .class_size = sizeof(Nios2CPUClass),
+    .class_init = nios2_cpu_class_init,
+};
+
+static void nios2_cpu_register_types(void)
+{
+    type_register_static(&nios2_cpu_type_info);
+}
+
+type_init(nios2_cpu_register_types)
diff --git a/target-nios2/cpu.h b/target-nios2/cpu.h
new file mode 100644
index 0000000..feac4fb
--- /dev/null
+++ b/target-nios2/cpu.h
@@ -0,0 +1,267 @@
+/*
+ * Altera Nios II virtual CPU header
+ *
+ * Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+#ifndef CPU_NIOS2_H
+#define CPU_NIOS2_H
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+
+#define TARGET_LONG_BITS 32
+
+#define CPUArchState struct CPUNios2State
+
+#include "exec/cpu-defs.h"
+#include "fpu/softfloat.h"
+#include "qom/cpu.h"
+struct CPUNios2State;
+typedef struct CPUNios2State CPUNios2State;
+#if !defined(CONFIG_USER_ONLY)
+#include "mmu.h"
+#endif
+
+#define TYPE_NIOS2_CPU "nios2-cpu"
+
+#define NIOS2_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(Nios2CPUClass, (klass), TYPE_NIOS2_CPU)
+#define NIOS2_CPU(obj) \
+    OBJECT_CHECK(Nios2CPU, (obj), TYPE_NIOS2_CPU)
+#define NIOS2_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(Nios2CPUClass, (obj), TYPE_NIOS2_CPU)
+
+/**
+ * Nios2CPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * A Nios2 CPU model.
+ */
+typedef struct Nios2CPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    DeviceRealize parent_realize;
+    void (*parent_reset)(CPUState *cpu);
+} Nios2CPUClass;
+
+#define TARGET_HAS_ICE 1
+
+/* Configuration options for Nios II */
+#define RESET_ADDRESS         0x00000000
+#define EXCEPTION_ADDRESS     0x00000004
+#define FAST_TLB_MISS_ADDRESS 0x00000008
+
+
+/* GP regs + CR regs + PC */
+#define NUM_CORE_REGS (32 + 32 + 1)
+
+/* General purpose register aliases */
+#define R_ZERO   0
+#define R_AT     1
+#define R_RET0   2
+#define R_RET1   3
+#define R_ARG0   4
+#define R_ARG1   5
+#define R_ARG2   6
+#define R_ARG3   7
+#define R_ET     24
+#define R_BT     25
+#define R_GP     26
+#define R_SP     27
+#define R_FP     28
+#define R_EA     29
+#define R_BA     30
+#define R_RA     31
+
+/* Control register aliases */
+#define CR_BASE  32
+#define CR_STATUS    (CR_BASE + 0)
+#define   CR_STATUS_PIE  (1<<0)
+#define   CR_STATUS_U    (1<<1)
+#define   CR_STATUS_EH   (1<<2)
+#define   CR_STATUS_IH   (1<<3)
+#define   CR_STATUS_IL   (63<<4)
+#define   CR_STATUS_CRS  (63<<10)
+#define   CR_STATUS_PRS  (63<<16)
+#define   CR_STATUS_NMI  (1<<22)
+#define   CR_STATUS_RSIE (1<<23)
+#define CR_ESTATUS   (CR_BASE + 1)
+#define CR_BSTATUS   (CR_BASE + 2)
+#define CR_IENABLE   (CR_BASE + 3)
+#define CR_IPENDING  (CR_BASE + 4)
+#define CR_CPUID     (CR_BASE + 5)
+#define CR_CTL6      (CR_BASE + 6)
+#define CR_EXCEPTION (CR_BASE + 7)
+#define CR_PTEADDR   (CR_BASE + 8)
+#define   CR_PTEADDR_PTBASE_SHIFT 22
+#define   CR_PTEADDR_PTBASE_MASK  (0x3FF << CR_PTEADDR_PTBASE_SHIFT)
+#define   CR_PTEADDR_VPN_SHIFT    2
+#define   CR_PTEADDR_VPN_MASK     (0xFFFFF << CR_PTEADDR_VPN_SHIFT)
+#define CR_TLBACC    (CR_BASE + 9)
+#define   CR_TLBACC_IGN_SHIFT 25
+#define   CR_TLBACC_IGN_MASK  (0x7F << CR_TLBACC_IGN_SHIFT)
+#define   CR_TLBACC_C         (1<<24)
+#define   CR_TLBACC_R         (1<<23)
+#define   CR_TLBACC_W         (1<<22)
+#define   CR_TLBACC_X         (1<<21)
+#define   CR_TLBACC_G         (1<<20)
+#define   CR_TLBACC_PFN_MASK  0x000FFFFF
+#define CR_TLBMISC   (CR_BASE + 10)
+#define   CR_TLBMISC_WAY_SHIFT 20
+#define   CR_TLBMISC_WAY_MASK  (0xF << CR_TLBMISC_WAY_SHIFT)
+#define   CR_TLBMISC_RD        (1<<19)
+#define   CR_TLBMISC_WR        (1<<18)
+#define   CR_TLBMISC_PID_SHIFT 4
+#define   CR_TLBMISC_PID_MASK  (0x3FFF << CR_TLBMISC_PID_SHIFT)
+#define   CR_TLBMISC_DBL       (1<<3)
+#define   CR_TLBMISC_BAD       (1<<2)
+#define   CR_TLBMISC_PERM      (1<<1)
+#define   CR_TLBMISC_D         (1<<0)
+#define CR_ENCINJ    (CR_BASE + 11)
+#define CR_BADADDR   (CR_BASE + 12)
+#define CR_CONFIG    (CR_BASE + 13)
+#define CR_MPUBASE   (CR_BASE + 14)
+#define CR_MPUACC    (CR_BASE + 15)
+
+/* Other registers */
+#define R_PC         64
+
+/* Exceptions */
+#define EXCP_BREAK    -1
+#define EXCP_RESET    0
+#define EXCP_PRESET   1
+#define EXCP_IRQ      2
+#define EXCP_TRAP     3
+#define EXCP_UNIMPL   4
+#define EXCP_ILLEGAL  5
+#define EXCP_UNALIGN  6
+#define EXCP_UNALIGND 7
+#define EXCP_DIV      8
+#define EXCP_SUPERA   9
+#define EXCP_SUPERI   10
+#define EXCP_SUPERD   11
+#define EXCP_TLBD     12
+#define EXCP_TLBX     13
+#define EXCP_TLBR     14
+#define EXCP_TLBW     15
+#define EXCP_MPUI     16
+#define EXCP_MPUD     17
+
+#define CPU_INTERRUPT_NMI       CPU_INTERRUPT_TGT_EXT_3
+
+#define NB_MMU_MODES 2
+
+struct CPUNios2State {
+    uint32_t regs[NUM_CORE_REGS];
+
+    /* Addresses that are hard-coded in the FPGA build settings */
+    uint32_t reset_addr;
+    uint32_t exception_addr;
+    uint32_t fast_tlb_miss_addr;
+
+#if !defined(CONFIG_USER_ONLY)
+    Nios2MMU mmu;
+
+    uint32_t irq_pending;
+#endif
+
+    CPU_COMMON
+};
+
+/**
+ * Nios2CPU:
+ * @env: #CPUNios2State
+ *
+ * A Nios2 CPU.
+ */
+typedef struct Nios2CPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUNios2State env;
+    bool mmu_present;
+} Nios2CPU;
+
+static inline Nios2CPU *nios2_env_get_cpu(CPUNios2State *env)
+{
+    return NIOS2_CPU(container_of(env, Nios2CPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(nios2_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(Nios2CPU, env)
+
+void nios2_tcg_init(void);
+Nios2CPU *cpu_nios2_init(const char *cpu_model);
+void nios2_cpu_do_interrupt(CPUState *cs);
+int cpu_nios2_signal_handler(int host_signum, void *pinfo, void *puc);
+void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUNios2State *env);
+void nios2_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                          int flags);
+hwaddr nios2_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+
+qemu_irq *nios2_cpu_pic_init(Nios2CPU *cpu);
+void nios2_check_interrupts(CPUNios2State *env);
+
+#define TARGET_PHYS_ADDR_SPACE_BITS 32
+#define TARGET_VIRT_ADDR_SPACE_BITS 32
+
+#define cpu_init(cpu_model) CPU(cpu_nios2_init(cpu_model))
+
+#define cpu_gen_code cpu_nios2_gen_code
+#define cpu_signal_handler cpu_nios2_signal_handler
+
+#define CPU_SAVE_VERSION 1
+
+#define TARGET_PAGE_BITS 12
+
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_SUPERVISOR_IDX  0
+#define MMU_USER_IDX        1
+
+static inline int cpu_mmu_index(CPUNios2State *env, bool ifetch)
+{
+    return (env->regs[CR_STATUS] & CR_STATUS_U) ? MMU_USER_IDX :
+                                                  MMU_SUPERVISOR_IDX;
+}
+
+int nios2_cpu_handle_mmu_fault(CPUState *env, vaddr address,
+                               int rw, int mmu_idx);
+
+static inline int cpu_interrupts_enabled(CPUNios2State *env)
+{
+    return env->regs[CR_STATUS] & CR_STATUS_PIE;
+}
+
+#include "exec/cpu-all.h"
+#include "exec/exec-all.h"
+
+static inline void cpu_get_tb_cpu_state(CPUNios2State *env, target_ulong *pc,
+                                        target_ulong *cs_base, uint32_t *flags)
+{
+    *pc = env->regs[R_PC];
+    *cs_base = 0;
+    *flags = (env->regs[CR_STATUS] & (CR_STATUS_EH | CR_STATUS_U));
+}
+
+#endif /* CPU_NIOS2_H */
+
diff --git a/target-nios2/helper.c b/target-nios2/helper.c
new file mode 100644
index 0000000..66fcd30
--- /dev/null
+++ b/target-nios2/helper.c
@@ -0,0 +1,304 @@
+/*
+ * Altera Nios II helper routines.
+ *
+ * Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "exec/log.h"
+#include "qemu/host-utils.h"
+
+#if defined(CONFIG_USER_ONLY)
+
+void nios2_cpu_do_interrupt(CPUState *cs)
+{
+    Nios2CPU *cpu = NIOS2_CPU(cs);
+    CPUNios2State *env = &cpu->env;
+    cs->exception_index = -1;
+    env->regs[R_EA] = env->regs[R_PC] + 4;
+}
+
+int nios2_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx)
+{
+    cs->exception_index = 0xaa;
+    /* Page 0x1000 is kuser helper */
+    if (address < 0x1000 || address >= 0x2000) {
+        cpu_dump_state(cs, stderr, fprintf, 0);
+    }
+    return 1;
+}
+
+#else /* !CONFIG_USER_ONLY */
+
+
+
+void nios2_cpu_do_interrupt(CPUState *cs)
+{
+    Nios2CPU *cpu = NIOS2_CPU(cs);
+    CPUNios2State *env = &cpu->env;
+
+    switch (cs->exception_index) {
+    case EXCP_IRQ:
+        assert(env->regs[CR_STATUS] & CR_STATUS_PIE);
+
+        qemu_log_mask(CPU_LOG_INT, "interrupt at pc=%x\n", env->regs[R_PC]);
+
+        env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
+        env->regs[CR_STATUS] |= CR_STATUS_IH;
+        env->regs[CR_STATUS] &= ~(CR_STATUS_PIE|CR_STATUS_U);
+
+        env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
+        env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+
+        env->regs[R_EA] = env->regs[R_PC] + 4;
+        env->regs[R_PC] = env->exception_addr;
+        break;
+
+    case EXCP_TLBD:
+        if ((env->regs[CR_STATUS] & CR_STATUS_EH) == 0) {
+            qemu_log_mask(CPU_LOG_INT, "TLB MISS (fast) at pc=%x\n",
+                          env->regs[R_PC]);
+
+            /* Fast TLB miss */
+            /* Variation from the spec. Table 3-35 of the cpu reference shows
+             * estatus not being changed for TLB miss but this appears to
+             * be incorrect. */
+            env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
+            env->regs[CR_STATUS] |= CR_STATUS_EH;
+            env->regs[CR_STATUS] &= ~(CR_STATUS_PIE|CR_STATUS_U);
+
+            env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
+            env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+
+            env->regs[CR_TLBMISC] &= ~CR_TLBMISC_DBL;
+            env->regs[CR_TLBMISC] |= CR_TLBMISC_WR;
+
+            env->regs[R_EA] = env->regs[R_PC] + 4;
+            env->regs[R_PC] = env->fast_tlb_miss_addr;
+        } else {
+            qemu_log_mask(CPU_LOG_INT, "TLB MISS (double) at pc=%x\n",
+                          env->regs[R_PC]);
+
+            /* Double TLB miss */
+            env->regs[CR_STATUS] |= CR_STATUS_EH;
+            env->regs[CR_STATUS] &= ~(CR_STATUS_PIE|CR_STATUS_U);
+
+            env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
+            env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+
+            env->regs[CR_TLBMISC] |= CR_TLBMISC_DBL;
+
+            env->regs[R_PC] = env->exception_addr;
+        }
+        break;
+
+    case EXCP_TLBR:
+    case EXCP_TLBW:
+    case EXCP_TLBX:
+        qemu_log_mask(CPU_LOG_INT, "TLB PERM at pc=%x\n", env->regs[R_PC]);
+
+        env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
+        env->regs[CR_STATUS] |= CR_STATUS_EH;
+        env->regs[CR_STATUS] &= ~(CR_STATUS_PIE|CR_STATUS_U);
+
+        env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
+        env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+
+        if ((env->regs[CR_STATUS] & CR_STATUS_EH) == 0) {
+            env->regs[CR_TLBMISC] |= CR_TLBMISC_WR;
+        }
+
+        env->regs[R_EA] = env->regs[R_PC] + 4;
+        env->regs[R_PC] = env->exception_addr;
+        break;
+
+    case EXCP_SUPERA:
+    case EXCP_SUPERI:
+    case EXCP_SUPERD:
+        qemu_log_mask(CPU_LOG_INT, "SUPERVISOR exception at pc=%x\n",
+                      env->regs[R_PC]);
+
+        if ((env->regs[CR_STATUS] & CR_STATUS_EH) == 0) {
+            env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
+            env->regs[R_EA] = env->regs[R_PC] + 4;
+        }
+
+        env->regs[CR_STATUS] |= CR_STATUS_EH;
+        env->regs[CR_STATUS] &= ~(CR_STATUS_PIE|CR_STATUS_U);
+
+        env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
+        env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+
+        env->regs[R_PC] = env->exception_addr;
+        break;
+
+    case EXCP_ILLEGAL:
+    case EXCP_TRAP:
+        qemu_log_mask(CPU_LOG_INT, "TRAP exception at pc=%x\n",
+                      env->regs[R_PC]);
+
+        if ((env->regs[CR_STATUS] & CR_STATUS_EH) == 0) {
+            env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
+            env->regs[R_EA] = env->regs[R_PC] + 4;
+        }
+
+        env->regs[CR_STATUS] |= CR_STATUS_EH;
+        env->regs[CR_STATUS] &= ~(CR_STATUS_PIE|CR_STATUS_U);
+
+        env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
+        env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+
+        env->regs[R_PC] = env->exception_addr;
+        break;
+
+    case EXCP_BREAK:
+        if ((env->regs[CR_STATUS] & CR_STATUS_EH) == 0) {
+            env->regs[CR_BSTATUS] = env->regs[CR_STATUS];
+            env->regs[R_BA] = env->regs[R_PC] + 4;
+        }
+
+        env->regs[CR_STATUS] |= CR_STATUS_EH;
+        env->regs[CR_STATUS] &= ~(CR_STATUS_PIE|CR_STATUS_U);
+
+        env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
+        env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+
+        env->regs[R_PC] = env->exception_addr;
+        break;
+
+    default:
+        cpu_abort(cs, "unhandled exception type=%d\n",
+                  cs->exception_index);
+        break;
+    }
+}
+
+static int cpu_nios2_handle_virtual_page(
+    CPUState *cs, target_ulong address, int rw, int mmu_idx)
+{
+    Nios2CPU *cpu = NIOS2_CPU(cs);
+    CPUNios2State *env = &cpu->env;
+    target_ulong vaddr, paddr;
+    Nios2MMULookup lu;
+    unsigned int hit;
+    hit = mmu_translate(env, &lu, address, rw, mmu_idx);
+    if (hit) {
+        vaddr = address & TARGET_PAGE_MASK;
+        paddr = lu.paddr + vaddr - lu.vaddr;
+
+        if (((rw == 0) && (lu.prot & PAGE_READ)) ||
+            ((rw == 1) && (lu.prot & PAGE_WRITE)) ||
+            ((rw == 2) && (lu.prot & PAGE_EXEC))) {
+
+            tlb_set_page(cs, vaddr, paddr, lu.prot,
+                         mmu_idx, TARGET_PAGE_SIZE);
+            return 0;
+        } else {
+            /* Permission violation */
+            cs->exception_index = (rw == 0) ? EXCP_TLBR :
+                                               ((rw == 1) ? EXCP_TLBW :
+                                                            EXCP_TLBX);
+        }
+    } else {
+        cs->exception_index = EXCP_TLBD;
+    }
+
+    if (rw == 2) {
+        env->regs[CR_TLBMISC] &= ~CR_TLBMISC_D;
+    } else {
+        env->regs[CR_TLBMISC] |= CR_TLBMISC_D;
+    }
+    env->regs[CR_PTEADDR] &= CR_PTEADDR_PTBASE_MASK;
+    env->regs[CR_PTEADDR] |= (address >> 10) & CR_PTEADDR_VPN_MASK;
+    env->mmu.pteaddr_wr = env->regs[CR_PTEADDR];
+    env->regs[CR_BADADDR] = address;
+    return 1;
+}
+
+int nios2_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx)
+{
+    Nios2CPU *cpu = NIOS2_CPU(cs);
+    CPUNios2State *env = &cpu->env;
+
+    if (cpu->mmu_present) {
+        if (MMU_SUPERVISOR_IDX == mmu_idx) {
+            if (address >= 0xC0000000) {
+                /* Kernel physical page - TLB bypassed */
+                address &= TARGET_PAGE_MASK;
+                tlb_set_page(cs, address, address, PAGE_BITS,
+                             mmu_idx, TARGET_PAGE_SIZE);
+            } else if (address >= 0x80000000) {
+                /* Kernel virtual page */
+                return cpu_nios2_handle_virtual_page(cs, address, rw, mmu_idx);
+            } else {
+                /* User virtual page */
+                return cpu_nios2_handle_virtual_page(cs, address, rw, mmu_idx);
+            }
+        } else {
+            if (address >= 0x80000000) {
+                /* Illegal access from user mode */
+                cs->exception_index = EXCP_SUPERA;
+                env->regs[CR_BADADDR] = address;
+                return 1;
+            } else {
+                /* User virtual page */
+                return cpu_nios2_handle_virtual_page(cs, address, rw, mmu_idx);
+            }
+        }
+    } else {
+        /* No MMU */
+        address &= TARGET_PAGE_MASK;
+        tlb_set_page(cs, address, address, PAGE_BITS,
+                     mmu_idx, TARGET_PAGE_SIZE);
+    }
+
+    return 0;
+}
+
+hwaddr nios2_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
+{
+    Nios2CPU *cpu = NIOS2_CPU(cs);
+    CPUNios2State *env = &cpu->env;
+    target_ulong vaddr, paddr = 0;
+    Nios2MMULookup lu;
+    unsigned int hit;
+
+    if (cpu->mmu_present && (addr < 0xC0000000)) {
+        hit = mmu_translate(env, &lu, addr, 0, 0);
+        if (hit) {
+            vaddr = addr & TARGET_PAGE_MASK;
+            paddr = lu.paddr + vaddr - lu.vaddr;
+        } else {
+            paddr = -1;
+            qemu_log("cpu_get_phys_page debug MISS: %08lX\n", addr);
+        }
+    } else {
+        paddr = addr & TARGET_PAGE_MASK;
+    }
+
+    return paddr;
+}
+
+#endif /* !CONFIG_USER_ONLY */
diff --git a/target-nios2/helper.h b/target-nios2/helper.h
new file mode 100644
index 0000000..7656a5e
--- /dev/null
+++ b/target-nios2/helper.h
@@ -0,0 +1,41 @@
+/*
+ * Altera Nios II helper routines header.
+ *
+ * Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+/* Define this to enable tracing calls/returns */
+/* #define CALL_TRACING */
+
+#ifdef CALL_TRACING
+DEF_HELPER_2(call_status, void, i32, i32)
+DEF_HELPER_1(eret_status, void, i32)
+DEF_HELPER_1(ret_status, void, i32)
+#endif
+
+DEF_HELPER_2(raise_exception, void, env, i32)
+
+#if !defined(CONFIG_USER_ONLY)
+DEF_HELPER_2(mmu_read, i32, env, i32)
+DEF_HELPER_3(mmu_write, void, env, i32, i32)
+DEF_HELPER_1(check_interrupts, void, env)
+#endif
+
+DEF_HELPER_2(divs, i32, i32, i32)
+DEF_HELPER_2(divu, i32, i32, i32)
+
+DEF_HELPER_5(memalign, void, env, i32, i32, i32, i32)
diff --git a/target-nios2/instruction.c b/target-nios2/instruction.c
new file mode 100644
index 0000000..2639cff
--- /dev/null
+++ b/target-nios2/instruction.c
@@ -0,0 +1,1427 @@
+/*
+ * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch>
+ *  (Portions of this file that were originally from nios2sim-ng.)
+ *
+ * Copyright (C) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include <stdio.h>
+
+#include "instruction.h"
+#include "exec/exec-all.h"
+#include "disas/disas.h"
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
+
+static inline uint32_t get_opcode(uint32_t code)
+{
+    I_TYPE(instr, code);
+    return instr->op;
+}
+
+static inline uint32_t get_opxcode(uint32_t code)
+{
+    R_TYPE(instr, code);
+    return instr->opx6;
+}
+
+static inline void t_gen_helper_raise_exception(DisasContext *dc,
+                                                uint32_t index)
+{
+    TCGv_i32 tmp = tcg_const_i32(index);
+
+    tcg_gen_movi_tl(dc->cpu_R[R_PC], dc->pc);
+    gen_helper_raise_exception(dc->cpu_env, tmp);
+    tcg_temp_free_i32(tmp);
+    dc->is_jmp = DISAS_UPDATE;
+}
+
+static inline void gen_goto_tb(DisasContext *dc, int n, uint32_t dest)
+{
+    TranslationBlock *tb = dc->tb;
+
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
+        tcg_gen_goto_tb(n);
+        tcg_gen_movi_tl(dc->cpu_R[R_PC], dest);
+        tcg_gen_exit_tb((tcg_target_long)tb + n);
+    } else {
+        tcg_gen_movi_tl(dc->cpu_R[R_PC], dest);
+        tcg_gen_exit_tb(0);
+    }
+}
+
+/*
+ * Instructions not implemented by the simulator.
+ */
+static void unimplemented(DisasContext *dc, uint32_t code)
+{
+    t_gen_helper_raise_exception(dc, EXCP_UNIMPL);
+}
+
+/*
+ * Illegal instruction
+ */
+static void illegal_instruction(DisasContext *dc,
+                                uint32_t code __attribute__((unused)))
+{
+    t_gen_helper_raise_exception(dc, EXCP_ILLEGAL);
+}
+
+static void gen_check_supervisor(DisasContext *dc, TCGLabel *label)
+{
+    TCGLabel *l1 = gen_new_label();
+
+    TCGv_i32 tmp = tcg_temp_new();
+    tcg_gen_andi_tl(tmp, dc->cpu_R[CR_STATUS], CR_STATUS_U);
+    tcg_gen_brcond_tl(TCG_COND_EQ, dc->cpu_R[R_ZERO], tmp, l1);
+    t_gen_helper_raise_exception(dc, EXCP_SUPERI);
+    tcg_gen_br(label);
+
+    gen_set_label(l1);
+    tcg_temp_free_i32(tmp);
+
+    /* If we aren't taking the exception, update the PC to the
+     * next instruction */
+    tcg_gen_movi_tl(dc->cpu_R[R_PC], dc->pc+4);
+}
+
+/*
+ * Used as a placeholder for all instructions which do not have an effect on the
+ * simulator (e.g. flush, sync)
+ */
+static void nop(DisasContext *dc __attribute__((unused)),
+                uint32_t code __attribute__((unused)))
+{
+    /* Nothing to do here */
+}
+
+/*
+ * J-Type instructions
+ */
+
+/*
+ * ra <- PC + 4
+ * PC <- (PC(31..28) : IMM26 * 4)
+ */
+static void call(DisasContext *dc, uint32_t code)
+{
+    J_TYPE(instr, code);
+
+#ifdef CALL_TRACING
+    TCGv_i32 tmp = tcg_const_i32(dc->pc);
+    TCGv_i32 tmp2 = tcg_const_i32((dc->pc & 0xF0000000) | (instr->imm26 * 4));
+    gen_helper_call_status(tmp, tmp2);
+    tcg_temp_free_i32(tmp);
+    tcg_temp_free_i32(tmp2);
+#endif
+
+    tcg_gen_movi_tl(dc->cpu_R[R_RA], dc->pc + 4);
+
+    gen_goto_tb(dc, 0, (dc->pc & 0xF0000000) | (instr->imm26 * 4));
+
+    dc->is_jmp = DISAS_TB_JUMP;
+}
+
+/* PC <- (PC(31..28) : IMM26 * 4) */
+static void jmpi(DisasContext *dc, uint32_t code)
+{
+    J_TYPE(instr, code);
+
+    gen_goto_tb(dc, 0, (dc->pc & 0xF0000000) | (instr->imm26 * 4));
+
+    dc->is_jmp = DISAS_TB_JUMP;
+}
+
+/*
+ * I-Type instructions
+ */
+
+/* rB <- 0x000000 : Mem8[rA + @(IMM16)] */
+static void ldbu(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_ld8u(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/* rB <- rA + IMM16 */
+static void addi(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv imm = tcg_temp_new();
+    tcg_gen_addi_tl(dc->cpu_R[instr->b], dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+    tcg_temp_free(imm);
+}
+
+/* Mem8[rA + @(IMM16)] <- rB(7..0) */
+static void stb(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_st8(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/* PC <- PC + 4 + IMM16 */
+static void br(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    gen_goto_tb(dc, 0, dc->pc + 4 + (int16_t)(instr->imm16 & 0xFFFC));
+
+    dc->is_jmp = DISAS_TB_JUMP;
+}
+
+/* rB <- @(Mem8[rA + @(IMM16)]) */
+static void ldb(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_ld8s(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/*
+ * if ((signed) rA >= (signed) @(IMM16))
+ *   rB <- 1
+ * else
+ *   rB <- 0
+ */
+static void cmpgei(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    tcg_gen_setcondi_tl(TCG_COND_GE, dc->cpu_R[instr->b], dc->cpu_R[instr->a],
+                        (int32_t)((int16_t)instr->imm16));
+}
+
+/* rB <- 0x0000 : Mem16[rA + @IMM16)] */
+static void ldhu(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_ld16u(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/* rB <- rA & IMM16 */
+static void andi(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    tcg_gen_andi_tl(dc->cpu_R[instr->b], dc->cpu_R[instr->a], instr->imm16);
+}
+
+/* Mem16[rA + @(IMM16)] <- rB(15..0) */
+static void sth(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_st16(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/*
+ * if ((signed) rA >= (signed) rB)
+ *   PC <- PC + 4 + @(IMM16)
+ * else
+ *   PC <- PC + 4
+ */
+static void bge(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGLabel *l1 = gen_new_label();
+
+    tcg_gen_brcond_tl(TCG_COND_GE, dc->cpu_R[instr->a],
+                      dc->cpu_R[instr->b], l1);
+
+    gen_goto_tb(dc, 0, dc->pc + 4);
+
+    gen_set_label(l1);
+
+    gen_goto_tb(dc, 1, dc->pc + 4 + (int16_t)(instr->imm16 & 0xFFFC));
+
+    dc->is_jmp = DISAS_TB_JUMP;
+}
+
+/* rB <- Mem16[rA + @IMM16)] */
+static void ldh(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_ld16s(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/*
+ * if ((signed) rA < (signed) @(IMM16))
+ *   rB <- 1
+ * else
+ *   rB <- 0
+ */
+static void cmplti(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    tcg_gen_setcondi_tl(TCG_COND_LT, dc->cpu_R[instr->b], dc->cpu_R[instr->a],
+                        (int32_t)((int16_t)instr->imm16));
+}
+
+/* Initializes the data cache line currently caching address rA + @(IMM16) */
+static void initda(DisasContext *dc __attribute__((unused)),
+                   uint32_t code __attribute__((unused)))
+{
+    /* TODO */
+}
+
+/* rB <- rA | IMM16 */
+static void ori(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    tcg_gen_ori_tl(dc->cpu_R[instr->b], dc->cpu_R[instr->a], instr->imm16);
+}
+
+/* Mem32[rA + @(IMM16)] <- rB */
+static void stw(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_st32(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/*
+ * if ((signed) rA < (signed) rB)
+ *   PC <- PC + 4 + @(IMM16)
+ * else
+ *   PC <- PC + 4
+ */
+static void blt(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGLabel *l1 = gen_new_label();
+
+    tcg_gen_brcond_tl(TCG_COND_LT, dc->cpu_R[instr->a],
+                      dc->cpu_R[instr->b], l1);
+
+    gen_goto_tb(dc, 0, dc->pc + 4);
+
+    gen_set_label(l1);
+
+    gen_goto_tb(dc, 1, dc->pc + 4 + (int16_t)(instr->imm16 & 0xFFFC));
+
+    dc->is_jmp = DISAS_TB_JUMP;
+}
+
+/* rB <- @(Mem32[rA + @(IMM16)]) */
+static void ldw(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_ld32u(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/*
+ * if ((signed) rA != (signed) @(IMM16))
+ *   rB <- 1
+ * else
+ *   rB <- 0
+ */
+static void cmpnei(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    tcg_gen_setcondi_tl(TCG_COND_NE, dc->cpu_R[instr->b], dc->cpu_R[instr->a],
+                        (int32_t)((int16_t)instr->imm16));
+}
+
+/* rB <- rA ^ IMM16 */
+static void xori(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    tcg_gen_xori_tl(dc->cpu_R[instr->b], dc->cpu_R[instr->a], instr->imm16);
+}
+
+/*
+ * if (rA != rB)
+ *   PC <- PC + 4 + @(IMM16)
+ * else
+ *   PC <- PC + 4
+ */
+static void bne(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGLabel *l1 = gen_new_label();
+
+    tcg_gen_brcond_tl(TCG_COND_NE, dc->cpu_R[instr->a],
+                      dc->cpu_R[instr->b], l1);
+
+    gen_goto_tb(dc, 0, dc->pc + 4);
+
+    gen_set_label(l1);
+
+    gen_goto_tb(dc, 1, dc->pc + 4 + (int16_t)(instr->imm16 & 0xFFFC));
+
+    dc->is_jmp = DISAS_TB_JUMP;
+}
+
+/*
+ * if ((signed) rA == (signed) @(IMM16))
+ *   rB <- 1
+ * else
+ *   rB <- 0
+ */
+static void cmpeqi(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    tcg_gen_setcondi_tl(TCG_COND_EQ, dc->cpu_R[instr->b], dc->cpu_R[instr->a],
+                        (int32_t)((int16_t)instr->imm16));
+}
+
+/* rB <- 0x000000 : Mem8[rA + @(IMM16)] (bypassing cache) */
+static void ldbuio(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_ld8u(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/* rB <- (rA * @(IMM16))(31..0) */
+static void muli(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv imm = tcg_temp_new();
+    tcg_gen_muli_i32(dc->cpu_R[instr->b], dc->cpu_R[instr->a],
+                     (int32_t)((int16_t)instr->imm16));
+    tcg_temp_free(imm);
+}
+
+/* Mem8[rA + @(IMM16)] <- rB(7..0) (bypassing cache) */
+static void stbio(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_st8(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/*
+ * if (rA == rB)
+ *   PC <- PC + 4 + @(IMM16)
+ * else
+ *   PC <- PC + 4
+ */
+static void beq(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGLabel *l1 = gen_new_label();
+
+    tcg_gen_brcond_tl(TCG_COND_EQ, dc->cpu_R[instr->a],
+                      dc->cpu_R[instr->b], l1);
+
+    gen_goto_tb(dc, 0, dc->pc + 4);
+
+    gen_set_label(l1);
+
+    gen_goto_tb(dc, 1, dc->pc + 4 + (int16_t)(instr->imm16 & 0xFFFC));
+
+    dc->is_jmp = DISAS_TB_JUMP;
+}
+
+/* rB <- @(Mem8[rA + @(IMM16)]) (bypassing cache) */
+static void ldbio(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_ld8s(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/*
+ * if (rA >= 0x0000 : @(IMM16))
+ *   rB <- 1
+ * else
+ *   rB <- 0
+ */
+static void cmpgeui(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    tcg_gen_setcondi_tl(TCG_COND_GEU, dc->cpu_R[instr->b], dc->cpu_R[instr->a],
+                        instr->imm16);
+}
+
+/* rB <- 0x0000 : Mem16[rA + @IMM16)] (bypassing cache) */
+static void ldhuio(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_ld16u(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/* rB <- rA & (IMM16 : 0x0000) */
+static void andhi(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    tcg_gen_andi_tl(dc->cpu_R[instr->b], dc->cpu_R[instr->a],
+                    instr->imm16 << 16);
+}
+
+/* Mem16[rA + @(IMM16)] <- rB(15..0) (bypassing cache) */
+static void sthio(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_st16(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/*
+ * if (rA >= rB)
+ *   PC <- PC + 4 + @(IMM16)
+ * else
+ *   PC <- PC + 4
+ */
+static void bgeu(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGLabel *l1 = gen_new_label();
+
+    tcg_gen_brcond_tl(TCG_COND_GEU, dc->cpu_R[instr->a],
+                      dc->cpu_R[instr->b], l1);
+
+    gen_goto_tb(dc, 0, dc->pc + 4);
+
+    gen_set_label(l1);
+
+    gen_goto_tb(dc, 1, dc->pc + 4 + (int16_t)(instr->imm16 & 0xFFFC));
+
+    dc->is_jmp = DISAS_TB_JUMP;
+}
+
+/* rB <- Mem16[rA + @IMM16)] (bypassing cache) */
+static void ldhio(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_ld16s(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/*
+ * if (rA < 0x0000 : @(IMM16))
+ *   rB <- 1
+ * else
+ *   rB <- 0
+ */
+static void cmpltui(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    tcg_gen_setcondi_tl(TCG_COND_LTU, dc->cpu_R[instr->b], dc->cpu_R[instr->a],
+                        instr->imm16);
+}
+
+/* */
+static void initd(DisasContext *dc __attribute__((unused)),
+                  uint32_t code __attribute((unused)))
+{
+    /* TODO */
+}
+
+/* rB <- rA | (IMM16 : 0x0000) */
+static void orhi(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    tcg_gen_ori_tl(dc->cpu_R[instr->b], dc->cpu_R[instr->a],
+                   instr->imm16 << 16);
+}
+
+/* Mem32[rA + @(IMM16)] <- rB (bypassing cache) */
+static void stwio(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_st32(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/*
+ * if ((unsigned) rA < (unsigned) rB)
+ *   PC <- PC + 4 + @(IMM16)
+ * else
+ *   PC <- PC + 4
+ */
+static void bltu(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGLabel *l1 = gen_new_label();
+
+    tcg_gen_brcond_tl(TCG_COND_LTU, dc->cpu_R[instr->a],
+                      dc->cpu_R[instr->b], l1);
+
+    gen_goto_tb(dc, 0, dc->pc + 4);
+
+    gen_set_label(l1);
+
+    gen_goto_tb(dc, 1, dc->pc + 4 + (int16_t)(instr->imm16 & 0xFFFC));
+
+    dc->is_jmp = DISAS_TB_JUMP;
+}
+
+/* rB <- @(Mem32[rA + @(IMM16)]) (bypassing cache) */
+static void ldwio(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    TCGv addr = tcg_temp_new();
+    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
+                    (int32_t)((int16_t)instr->imm16));
+
+    tcg_gen_qemu_ld32u(dc->cpu_R[instr->b], addr, dc->mem_idx);
+
+    tcg_temp_free(addr);
+}
+
+/* Prototype only, defined below */
+static void handle_r_type_instr(DisasContext *dc, uint32_t code);
+
+/* rB <- rA ^ (IMM16 : 0x0000) */
+static void xorhi(DisasContext *dc, uint32_t code)
+{
+    I_TYPE(instr, code);
+
+    tcg_gen_xori_tl(dc->cpu_R[instr->b], dc->cpu_R[instr->a],
+                    instr->imm16 << 16);
+}
+
+static const Nios2Instruction i_type_instructions[I_TYPE_COUNT] = {
+    [CALL]    = INSTRUCTION(call),
+    [JMPI]    = INSTRUCTION(jmpi),
+    [0x02]    = INSTRUCTION_ILLEGAL(),
+    [LDBU]    = INSTRUCTION(ldbu),
+    [ADDI]    = INSTRUCTION(addi),
+    [STB]     = INSTRUCTION(stb),
+    [BR]      = INSTRUCTION(br),
+    [LDB]     = INSTRUCTION(ldb),
+    [CMPGEI]  = INSTRUCTION(cmpgei),
+    [0x09]    = INSTRUCTION_ILLEGAL(),
+    [0x0a]    = INSTRUCTION_ILLEGAL(),
+    [LDHU]    = INSTRUCTION(ldhu),
+    [ANDI]    = INSTRUCTION(andi),
+    [STH]     = INSTRUCTION(sth),
+    [BGE]     = INSTRUCTION(bge),
+    [LDH]     = INSTRUCTION(ldh),
+    [CMPLTI]  = INSTRUCTION(cmplti),
+    [0x11]    = INSTRUCTION_ILLEGAL(),
+    [0x12]    = INSTRUCTION_ILLEGAL(),
+    [INITDA]  = INSTRUCTION(initda),
+    [ORI]     = INSTRUCTION(ori),
+    [STW]     = INSTRUCTION(stw),
+    [BLT]     = INSTRUCTION(blt),
+    [LDW]     = INSTRUCTION(ldw),
+    [CMPNEI]  = INSTRUCTION(cmpnei),
+    [0x19]    = INSTRUCTION_ILLEGAL(),
+    [0x1a]    = INSTRUCTION_ILLEGAL(),
+    [FLUSHDA] = INSTRUCTION_NOP(flushda),
+    [XORI]    = INSTRUCTION(xori),
+    [0x1d]    = INSTRUCTION_ILLEGAL(),
+    [BNE]     = INSTRUCTION(bne),
+    [0x1f]    = INSTRUCTION_ILLEGAL(),
+    [CMPEQI]  = INSTRUCTION(cmpeqi),
+    [0x21]    = INSTRUCTION_ILLEGAL(),
+    [0x22]    = INSTRUCTION_ILLEGAL(),
+    [LDBUIO]  = INSTRUCTION(ldbuio),
+    [MULI]    = INSTRUCTION(muli),
+    [STBIO]   = INSTRUCTION(stbio),
+    [BEQ]     = INSTRUCTION(beq),
+    [LDBIO]   = INSTRUCTION(ldbio),
+    [CMPGEUI] = INSTRUCTION(cmpgeui),
+    [0x29]    = INSTRUCTION_ILLEGAL(),
+    [0x2a]    = INSTRUCTION_ILLEGAL(),
+    [LDHUIO]  = INSTRUCTION(ldhuio),
+    [ANDHI]   = INSTRUCTION(andhi),
+    [STHIO]   = INSTRUCTION(sthio),
+    [BGEU]    = INSTRUCTION(bgeu),
+    [LDHIO]   = INSTRUCTION(ldhio),
+    [CMPLTUI] = INSTRUCTION(cmpltui),
+    [0x31]    = INSTRUCTION_ILLEGAL(),
+    [CUSTOM]  = INSTRUCTION_UNIMPLEMENTED(custom),
+    [INITD]   = INSTRUCTION(initd),
+    [ORHI]    = INSTRUCTION(orhi),
+    [STWIO]   = INSTRUCTION(stwio),
+    [BLTU]    = INSTRUCTION(bltu),
+    [LDWIO]   = INSTRUCTION(ldwio),
+    [RDPRS]   = INSTRUCTION_UNIMPLEMENTED(rdprs),
+    [0x39]    = INSTRUCTION_ILLEGAL(),
+    [R_TYPE]  = { "<R-type instruction>", handle_r_type_instr },
+    [FLUSHD]  = INSTRUCTION_NOP(flushd),
+    [XORHI]   = INSTRUCTION(xorhi),
+    [0x3d]    = INSTRUCTION_ILLEGAL(),
+    [0x3e]    = INSTRUCTION_ILLEGAL(),
+    [0x3f]    = INSTRUCTION_ILLEGAL(),
+};
+
+/*
+ * R-Type instructions
+ */
+
+/*
+ * status <- estatus
+ * PC <- ea
+ */
+static void eret(DisasContext *dc, uint32_t code __attribute__((unused)))
+{
+#ifdef CALL_TRACING
+    TCGv_i32 tmp = tcg_const_i32(dc->pc);
+    gen_helper_eret_status(tmp);
+    tcg_temp_free_i32(tmp);
+#endif
+
+    tcg_gen_mov_tl(dc->cpu_R[CR_STATUS], dc->cpu_R[CR_ESTATUS]);
+    tcg_gen_mov_tl(dc->cpu_R[R_PC], dc->cpu_R[R_EA]);
+
+    dc->is_jmp = DISAS_JUMP;
+}
+
+/* rC <- rA rotated left IMM5 bit positions */
+static void roli(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_rotli_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], instr->imm5);
+}
+
+/* rC <- rA rotated left rB(4..0) bit positions */
+static void rol(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_andi_tl(t0, dc->cpu_R[instr->b], 31);
+    tcg_gen_rotl_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], t0);
+
+    tcg_temp_free(t0);
+}
+
+/* */
+static void flushp(DisasContext *dc __attribute__((unused)),
+                   uint32_t code __attribute__((unused)))
+{
+    /* TODO */
+}
+
+/* PC <- ra */
+static void ret(DisasContext *dc, uint32_t code __attribute__((unused)))
+{
+#ifdef CALL_TRACING
+    TCGv_i32 tmp = tcg_const_i32(dc->pc);
+    gen_helper_ret_status(tmp);
+    tcg_temp_free_i32(tmp);
+#endif
+
+    tcg_gen_mov_tl(dc->cpu_R[R_PC], dc->cpu_R[R_RA]);
+
+    dc->is_jmp = DISAS_JUMP;
+}
+
+/* rC <- ~(A | rB) */
+static void nor(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_nor_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                   dc->cpu_R[instr->b]);
+}
+
+/* rC <- ((unsigned)rA * (unsigned)rB))(31..0) */
+static void mulxuu(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    TCGv_i64 t0, t1;
+
+    t0 = tcg_temp_new_i64();
+    t1 = tcg_temp_new_i64();
+
+    tcg_gen_extu_i32_i64(t0, dc->cpu_R[instr->a]);
+    tcg_gen_extu_i32_i64(t1, dc->cpu_R[instr->b]);
+    tcg_gen_mul_i64(t0, t0, t1);
+
+    tcg_gen_shri_i64(t0, t0, 32);
+    tcg_gen_extrl_i64_i32(dc->cpu_R[instr->c], t0);
+
+    tcg_temp_free_i64(t0);
+    tcg_temp_free_i64(t1);
+}
+
+/*
+ * if (rA >= rB)
+ *   rC <- 1
+ * else
+ *   rC <- 0
+ */
+static void cmpge(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_setcond_tl(TCG_COND_GE, dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                       dc->cpu_R[instr->b]);
+}
+
+/* PC <- ba */
+static void bret(DisasContext *dc, uint32_t code __attribute__((unused)))
+{
+    tcg_gen_mov_tl(dc->cpu_R[R_PC], dc->cpu_R[R_BA]);
+
+    dc->is_jmp = DISAS_JUMP;
+}
+
+/*  rC <- rA rotated right rb(4..0) bit positions */
+static void ror(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_andi_tl(t0, dc->cpu_R[instr->b], 31);
+    tcg_gen_rotr_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], t0);
+
+    tcg_temp_free(t0);
+}
+
+/* */
+static void flushi(DisasContext *dc __attribute__((unused)),
+                   uint32_t code __attribute__((unused)))
+{
+    /* TODO */
+}
+
+/* PC <- rA */
+static void jmp(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_mov_tl(dc->cpu_R[R_PC], dc->cpu_R[instr->a]);
+
+    dc->is_jmp = DISAS_JUMP;
+}
+
+/* rC <- rA & rB */
+static void and(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_and_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                   dc->cpu_R[instr->b]);
+}
+
+/*
+ * if ((signed) rA < (signed) rB)
+ *   rC <- 1
+ * else
+ *   rC <- 0
+ */
+static void cmplt(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_setcond_tl(TCG_COND_LT, dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                       dc->cpu_R[instr->b]);
+}
+
+/* rC <- rA << IMM5 */
+static void slli(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_shli_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], instr->imm5);
+}
+
+/* rC <- rA << rB(4..0) */
+static void sll(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_andi_tl(t0, dc->cpu_R[instr->b], 31);
+    tcg_gen_shl_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], t0);
+
+    tcg_temp_free(t0);
+}
+
+/* rC <- rA | rB */
+static void or(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_or_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                  dc->cpu_R[instr->b]);
+}
+
+/* rC <- ((signed)rA * (unsigned)rB))(31..0) */
+static void mulxsu(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    TCGv_i64 t0, t1;
+
+    t0 = tcg_temp_new_i64();
+    t1 = tcg_temp_new_i64();
+
+    tcg_gen_ext_i32_i64(t0, dc->cpu_R[instr->a]);
+    tcg_gen_extu_i32_i64(t1, dc->cpu_R[instr->b]);
+    tcg_gen_mul_i64(t0, t0, t1);
+
+    tcg_gen_shri_i64(t0, t0, 32);
+    tcg_gen_extrl_i64_i32(dc->cpu_R[instr->c], t0);
+
+    tcg_temp_free_i64(t0);
+    tcg_temp_free_i64(t1);
+}
+
+/*
+ * if (rA != rB)
+ *   rC <- 1
+ * else
+ *   rC <- 0
+ */
+static void cmpne(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_setcond_tl(TCG_COND_NE, dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                       dc->cpu_R[instr->b]);
+}
+
+/* rC <- (unsigned) rA >> ((unsigned) IMM5)*/
+static void srli(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_shri_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], instr->imm5);
+}
+
+/* rC <- (unsigned) rA >> ((unsigned) rB(4..0))*/
+static void srl(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_andi_tl(t0, dc->cpu_R[instr->b], 31);
+    tcg_gen_shr_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], t0);
+
+    tcg_temp_free(t0);
+}
+
+/* rC <- PC + 4 */
+static void nextpc(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_movi_tl(dc->cpu_R[instr->c], dc->pc + 4);
+}
+
+/*
+ * ra <- PC + 4
+ * PC <- rA
+ */
+static void callr(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+#ifdef CALL_TRACING
+    TCGv_i32 tmp = tcg_const_i32(dc->pc);
+    gen_helper_call_status(tmp, dc->cpu_R[instr->a]);
+    tcg_temp_free_i32(tmp);
+#endif
+
+    tcg_gen_movi_tl(dc->cpu_R[R_RA], dc->pc + 4);
+    tcg_gen_mov_tl(dc->cpu_R[R_PC], dc->cpu_R[instr->a]);
+
+    dc->is_jmp = DISAS_JUMP;
+}
+
+/* rC <- rA ^ rB */
+static void xor(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_xor_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                   dc->cpu_R[instr->b]);
+}
+
+/* rC <- ((signed)rA * (signed)rB))(31..0) */
+static void mulxss(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    TCGv_i64 t0, t1;
+
+    t0 = tcg_temp_new_i64();
+    t1 = tcg_temp_new_i64();
+
+    tcg_gen_ext_i32_i64(t0, dc->cpu_R[instr->a]);
+    tcg_gen_ext_i32_i64(t1, dc->cpu_R[instr->b]);
+    tcg_gen_mul_i64(t0, t0, t1);
+
+    tcg_gen_shri_i64(t0, t0, 32);
+    tcg_gen_extrl_i64_i32(dc->cpu_R[instr->c], t0);
+
+    tcg_temp_free_i64(t0);
+    tcg_temp_free_i64(t1);
+}
+
+/*
+ * if (rA == rB)
+ *   rC <- 1
+ * else
+ *   rC <- 0
+ */
+static void cmpeq(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_setcond_tl(TCG_COND_EQ, dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                       dc->cpu_R[instr->b]);
+}
+
+/* rC <- rA / rB */
+static void divu(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    gen_helper_divu(dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                    dc->cpu_R[instr->b]);
+}
+
+/* rC <- rA / rB */
+static void _div(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    gen_helper_divs(dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                    dc->cpu_R[instr->b]);
+}
+
+/* rC <- ctlN */
+static void rdctl(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    TCGLabel *l1 = gen_new_label();
+    gen_check_supervisor(dc, l1);
+
+    switch (instr->imm5 + 32) {
+    case CR_PTEADDR:
+    case CR_TLBACC:
+    case CR_TLBMISC:
+    {
+#if !defined(CONFIG_USER_ONLY)
+        TCGv_i32 tmp = tcg_const_i32(instr->imm5 + 32);
+        gen_helper_mmu_read(dc->cpu_R[instr->c], dc->cpu_env, tmp);
+        tcg_temp_free_i32(tmp);
+#endif
+        break;
+    }
+
+    default:
+        tcg_gen_mov_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->imm5 + 32]);
+        break;
+    }
+
+    gen_set_label(l1);
+}
+
+/* rC <- (rA * rB))(31..0) */
+static void mul(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_mul_i32(dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                    dc->cpu_R[instr->b]);
+}
+
+/*
+ * if (rA >= rB)
+ *   rC <- 1
+ * else
+ *   rC <- 0
+ */
+static void cmpgeu(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_setcond_tl(TCG_COND_GEU, dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                       dc->cpu_R[instr->b]);
+}
+
+/* */
+static void initi(DisasContext *dc __attribute__((unused)),
+                  uint32_t code __attribute__((unused)))
+{
+    /* TODO */
+}
+
+/*
+ * estatus <- status
+ * PIE <- 0
+ * U <- 0
+ * ea <- PC + 4
+ * PC <- exception handler address
+ */
+static void trap(DisasContext *dc, uint32_t code __attribute__((unused)))
+{
+    t_gen_helper_raise_exception(dc, EXCP_TRAP);
+}
+
+/* ctlN <- rA */
+static void wrctl(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    TCGLabel *l1 = gen_new_label();
+    gen_check_supervisor(dc, l1);
+
+    switch (instr->imm5 + 32) {
+    case CR_PTEADDR:
+    case CR_TLBACC:
+    case CR_TLBMISC:
+    {
+#if !defined(CONFIG_USER_ONLY)
+        TCGv_i32 tmp = tcg_const_i32(instr->imm5 + 32);
+        gen_helper_mmu_write(dc->cpu_env, tmp, dc->cpu_R[instr->a]);
+        tcg_temp_free_i32(tmp);
+#endif
+        break;
+    }
+
+    default:
+        tcg_gen_mov_tl(dc->cpu_R[instr->imm5 + 32], dc->cpu_R[instr->a]);
+        break;
+    }
+
+    /* If interrupts were enabled using WRCTL, trigger them. */
+#if !defined(CONFIG_USER_ONLY)
+    if ((instr->imm5 + 32) == CR_STATUS) {
+        gen_helper_check_interrupts(dc->cpu_env);
+    }
+#endif
+
+    gen_set_label(l1);
+}
+
+/*
+ * if (rA < rB)
+ *   rC <- 1
+ * else
+ *   rC <- 0
+ */
+static void cmpltu(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_setcond_tl(TCG_COND_LTU, dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                       dc->cpu_R[instr->b]);
+}
+
+/* rC <- rA + rB */
+static void add(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_add_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                   dc->cpu_R[instr->b]);
+}
+
+/*
+ * bstatus ← status
+ * PIE <- 0
+ * U <- 0
+ * ba <- PC + 4
+ * PC <- break handler address
+ */
+static void __break(DisasContext *dc, uint32_t code __attribute__((unused)))
+{
+    t_gen_helper_raise_exception(dc, EXCP_BREAK);
+}
+
+/* rC <- rA - rB */
+static void sub(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_sub_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a],
+                   dc->cpu_R[instr->b]);
+}
+
+/* rC <- (signed) rA >> ((unsigned) IMM5) */
+static void srai(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    tcg_gen_sari_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], instr->imm5);
+}
+
+/* rC <- (signed) rA >> ((unsigned) rB(4..0)) */
+static void sra(DisasContext *dc, uint32_t code)
+{
+    R_TYPE(instr, code);
+
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_andi_tl(t0, dc->cpu_R[instr->b], 31);
+    tcg_gen_sar_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], t0);
+
+    tcg_temp_free(t0);
+}
+
+static const Nios2Instruction r_type_instructions[R_TYPE_COUNT] = {
+    [0x00]   = INSTRUCTION_ILLEGAL(),
+    [ERET]   = INSTRUCTION(eret),
+    [ROLI]   = INSTRUCTION(roli),
+    [ROL]    = INSTRUCTION(rol),
+    [FLUSHP] = INSTRUCTION(flushp),
+    [RET]    = INSTRUCTION(ret),
+    [NOR]    = INSTRUCTION(nor),
+    [MULXUU] = INSTRUCTION(mulxuu),
+    [CMPGE]  = INSTRUCTION(cmpge),
+    [BRET]   = INSTRUCTION(bret),
+    [0x0a]   = INSTRUCTION_ILLEGAL(),
+    [ROR]    = INSTRUCTION(ror),
+    [FLUSHI] = INSTRUCTION(flushi),
+    [JMP]    = INSTRUCTION(jmp),
+    [AND]    = INSTRUCTION(and),
+    [0x0f]   = INSTRUCTION_ILLEGAL(),
+    [CMPLT]  = INSTRUCTION(cmplt),
+    [0x11]   = INSTRUCTION_ILLEGAL(),
+    [SLLI]   = INSTRUCTION(slli),
+    [SLL]    = INSTRUCTION(sll),
+    [WRPRS]  = INSTRUCTION_UNIMPLEMENTED(wrprs),
+    [0x15]   = INSTRUCTION_ILLEGAL(),
+    [OR]     = INSTRUCTION(or),
+    [MULXSU] = INSTRUCTION(mulxsu),
+    [CMPNE]  = INSTRUCTION(cmpne),
+    [0x19]   = INSTRUCTION_ILLEGAL(),
+    [SRLI]   = INSTRUCTION(srli),
+    [SRL]    = INSTRUCTION(srl),
+    [NEXTPC] = INSTRUCTION(nextpc),
+    [CALLR]  = INSTRUCTION(callr),
+    [XOR]    = INSTRUCTION(xor),
+    [MULXSS] = INSTRUCTION(mulxss),
+    [CMPEQ]  = INSTRUCTION(cmpeq),
+    [0x21]   = INSTRUCTION_ILLEGAL(),
+    [0x22]   = INSTRUCTION_ILLEGAL(),
+    [0x23]   = INSTRUCTION_ILLEGAL(),
+    [DIVU]   = INSTRUCTION(divu),
+    [DIV]    = { "div", _div },
+    [RDCTL]  = INSTRUCTION(rdctl),
+    [MUL]    = INSTRUCTION(mul),
+    [CMPGEU] = INSTRUCTION(cmpgeu),
+    [INITI]  = INSTRUCTION(initi),
+    [0x2a]   = INSTRUCTION_ILLEGAL(),
+    [0x2b]   = INSTRUCTION_ILLEGAL(),
+    [0x2c]   = INSTRUCTION_ILLEGAL(),
+    [TRAP]   = INSTRUCTION(trap),
+    [WRCTL]  = INSTRUCTION(wrctl),
+    [0x2f]   = INSTRUCTION_ILLEGAL(),
+    [CMPLTU] = INSTRUCTION(cmpltu),
+    [ADD]    = INSTRUCTION(add),
+    [0x32]   = INSTRUCTION_ILLEGAL(),
+    [0x33]   = INSTRUCTION_ILLEGAL(),
+    [BREAK]  = { "break", __break },
+    [0x35]   = INSTRUCTION_ILLEGAL(),
+    [SYNC]   = INSTRUCTION(nop),
+    [0x37]   = INSTRUCTION_ILLEGAL(),
+    [0x38]   = INSTRUCTION_ILLEGAL(),
+    [SUB]    = INSTRUCTION(sub),
+    [SRAI]   = INSTRUCTION(srai),
+    [SRA]    = INSTRUCTION(sra),
+    [0x3c]   = INSTRUCTION_ILLEGAL(),
+    [0x3d]   = INSTRUCTION_ILLEGAL(),
+    [0x3e]   = INSTRUCTION_ILLEGAL(),
+    [0x3f]   = INSTRUCTION_ILLEGAL(),
+};
+
+static void handle_r_type_instr(DisasContext *dc, uint32_t code)
+{
+    uint32_t opx;
+    instruction_handler handle_instr;
+
+    opx = get_opxcode(code);
+    if (unlikely(opx >= R_TYPE_COUNT)) {
+        goto illegal_op;
+    }
+
+    LOG_DIS("R: %s (%08x)\n", r_type_instructions[opx].name, code);
+    handle_instr = r_type_instructions[opx].handler;
+
+    handle_instr(dc, code);
+
+    return;
+
+illegal_op:
+    t_gen_helper_raise_exception(dc, EXCP_ILLEGAL);
+}
+
+#include "exec/cpu_ldst.h"
+
+void handle_instruction(DisasContext *dc, CPUNios2State *env)
+{
+    uint32_t insn;
+    uint32_t op;
+#if defined(CONFIG_USER_ONLY)
+    /* FIXME: Is this needed ? */
+    if (dc->pc >= 0x1000 && dc->pc < 0x2000) {
+        env->regs[R_PC] = dc->pc;
+        t_gen_helper_raise_exception(dc, 0xaa);
+       return;
+    }
+#endif
+    insn = cpu_ldl_code(env, dc->pc);
+    op = get_opcode(insn);
+
+    LOG_DIS("%8.8x\t", insn);
+
+    if (unlikely(op >= I_TYPE_COUNT)) {
+        goto illegal_op;
+    }
+
+    if (op != R_TYPE) {
+        LOG_DIS("I: %s (%08x)\n", i_type_instructions[op].name, insn);
+    }
+    i_type_instructions[op].handler(dc, insn);
+
+    return;
+
+illegal_op:
+    t_gen_helper_raise_exception(dc, EXCP_ILLEGAL);
+}
+
+const char *instruction_get_string(uint32_t code)
+{
+    uint32_t op = get_opcode(code);
+
+    if (unlikely(op >= I_TYPE_COUNT)) {
+        return "";
+    } else if (op == R_TYPE) {
+        uint32_t opx = get_opxcode(code);
+        if (unlikely(opx >= R_TYPE_COUNT)) {
+            return "";
+        }
+        return r_type_instructions[opx].name;
+    } else {
+        return i_type_instructions[op].name;
+    }
+}
+
diff --git a/target-nios2/instruction.h b/target-nios2/instruction.h
new file mode 100644
index 0000000..3758899
--- /dev/null
+++ b/target-nios2/instruction.h
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch>
+ * Copyright (C) 2010 chysun2000@gmail.com
+ *  (Portions of this file that were originally from nios2sim-ng.)
+ *
+ * Copyright (C) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#ifndef _INSTRUCTION_H_
+#define _INSTRUCTION_H_
+
+#include <stdint.h>
+#include "cpu.h"
+#include "tcg-op.h"
+
+/*
+ * Instruction Word Formats
+ */
+
+/* I-Type instruction */
+typedef struct Nios2IType {
+    uint32_t op:6;
+    uint32_t imm16:16;
+    uint32_t b:5;
+    uint32_t a:5;
+} QEMU_PACKED Nios2IType;
+
+union i_type_u {
+    uint32_t      v;
+    Nios2IType i;
+};
+
+#define I_TYPE(instr, op) \
+    union i_type_u instr_u = { .v = op }; \
+    Nios2IType *instr = &instr_u.i
+
+/* R-Type instruction */
+typedef struct Nios2RType {
+    uint32_t op:6;
+    /*
+     * Some R-Type instructions embed a small immediate value in the
+     * low-order bits of OPX.
+     */
+    uint32_t imm5:5;
+    uint32_t opx6:6;
+    uint32_t c:5;
+    uint32_t b:5;
+    uint32_t a:5;
+} QEMU_PACKED Nios2RType;
+
+union r_type_u {
+    uint32_t      v;
+    Nios2RType i;
+};
+
+#define R_TYPE(instr, op) \
+    union r_type_u instr_u = { .v = op }; \
+    Nios2RType *instr = &instr_u.i
+
+/* J-Type instruction */
+typedef struct Nios2JType {
+    uint32_t op:6;
+    uint32_t imm26:26;
+} QEMU_PACKED Nios2JType;
+
+#define J_TYPE(instr, op) \
+    Nios2JType *instr = (Nios2JType *) &op
+
+/*
+ * Instruction Opcodes
+ */
+
+/*
+ * OP Encodings for I-Type instructions (except for CALL and JMPI, which are
+ * J-type instructions)
+ */
+enum {
+    CALL    = 0x00,  /* J-type */
+    JMPI    = 0x01,  /* J-type */
+           /* 0x02 */
+    LDBU    = 0x03,
+    ADDI    = 0x04,
+    STB     = 0x05,
+    BR      = 0x06,
+    LDB     = 0x07,
+    CMPGEI  = 0x08,
+           /* 0x09 */
+           /* 0x0A */
+    LDHU    = 0x0B,
+    ANDI    = 0x0C,
+    STH     = 0x0D,
+    BGE     = 0x0E,
+    LDH     = 0x0F,
+    CMPLTI  = 0x10,
+           /* 0x11 */
+           /* 0x12 */
+    INITDA  = 0x13,
+    ORI     = 0x14,
+    STW     = 0x15,
+    BLT     = 0x16,
+    LDW     = 0x17,
+    CMPNEI  = 0x18,
+           /* 0x19 */
+           /* 0x1A */
+    FLUSHDA = 0x1B,
+    XORI    = 0x1C,
+           /* 0x1D */
+    BNE     = 0x1E,
+           /* 0x1F */
+    CMPEQI  = 0x20,
+           /* 0x21 */
+           /* 0x22 */
+    LDBUIO  = 0x23,
+    MULI    = 0x24,
+    STBIO   = 0x25,
+    BEQ     = 0x26,
+    LDBIO   = 0x27,
+    CMPGEUI = 0x28,
+           /* 0x29 */
+           /* 0x2A */
+    LDHUIO  = 0x2B,
+    ANDHI   = 0x2C,
+    STHIO   = 0x2D,
+    BGEU    = 0x2E,
+    LDHIO   = 0x2F,
+    CMPLTUI = 0x30,
+           /* 0x31 */
+    CUSTOM  = 0x32,
+    INITD   = 0x33,
+    ORHI    = 0x34,
+    STWIO   = 0x35,
+    BLTU    = 0x36,
+    LDWIO   = 0x37,
+    RDPRS   = 0x38,
+           /* 0x39 */
+    R_TYPE  = 0x3A,
+    FLUSHD  = 0x3B,
+    XORHI   = 0x3C,
+           /* 0x3D */
+           /* 0x3E */
+           /* 0x3F */
+};
+#define I_TYPE_COUNT  0x40
+
+/* OPX Encodings for R-Type instructions */
+enum {
+          /* 0x00 */
+    ERET   = 0x01,
+    ROLI   = 0x02,
+    ROL    = 0x03,
+    FLUSHP = 0x04,
+    RET    = 0x05,
+    NOR    = 0x06,
+    MULXUU = 0x07,
+    CMPGE  = 0x08,
+    BRET   = 0x09,
+          /* 0x0A */
+    ROR    = 0x0B,
+    FLUSHI = 0x0C,
+    JMP    = 0x0D,
+    AND    = 0x0E,
+          /* 0x0F */
+    CMPLT  = 0x10,
+          /* 0x11 */
+    SLLI   = 0x12,
+    SLL    = 0x13,
+    WRPRS  = 0x14,
+          /* 0x15 */
+    OR     = 0x16,
+    MULXSU = 0x17,
+    CMPNE  = 0x18,
+          /* 0x19 */
+    SRLI   = 0x1A,
+    SRL    = 0x1B,
+    NEXTPC = 0x1C,
+    CALLR  = 0x1D,
+    XOR    = 0x1E,
+    MULXSS = 0x1F,
+    CMPEQ  = 0x20,
+          /* 0x21 */
+          /* 0x22 */
+          /* 0x23 */
+    DIVU   = 0x24,
+    DIV    = 0x25,
+    RDCTL  = 0x26,
+    MUL    = 0x27,
+    CMPGEU = 0x28,
+    INITI  = 0x29,
+          /* 0x2A */
+          /* 0x2B */
+          /* 0x2C */
+    TRAP   = 0x2D,
+    WRCTL  = 0x2E,
+          /* 0x2F */
+    CMPLTU = 0x30,
+    ADD    = 0x31,
+          /* 0x32 */
+          /* 0x33 */
+    BREAK  = 0x34,
+          /* 0x35 */
+    SYNC   = 0x36,
+          /* 0x37 */
+          /* 0x38 */
+    SUB    = 0x39,
+    SRAI   = 0x3A,
+    SRA    = 0x3B,
+          /* 0x3C */
+          /* 0x3D */
+          /* 0x3E */
+          /* 0x3F */
+};
+#define R_TYPE_COUNT  0x40
+
+/*
+ * Return values for instruction handlers
+ */
+#define INSTR_UNIMPL     -2  /* Unimplemented instruction */
+#define INSTR_ERR        -1  /* Error in instruction */
+#define PC_INC_NORMAL     0  /* Normal PC increment after instruction */
+#define PC_INC_BY_INSTR   1  /* PC got incremented by instruction */
+#define INSTR_BREAK       2  /* Break encountered */
+#define INSTR_EXCEPTION 255  /* Instruction generated an exception
+                                (the exception cause will be stored
+                                in struct nios2 */
+
+#define EXCEPTION(cpu, cause)           \
+    ({                                  \
+        (cpu)->exception_cause = cause; \
+        INSTR_EXCEPTION;                \
+    })
+
+typedef struct DisasContext {
+    TCGv_ptr          cpu_env;
+    TCGv             *cpu_R;
+    int               is_jmp;
+    target_ulong      pc;
+    TranslationBlock *tb;
+    int               mem_idx;
+} DisasContext;
+
+typedef void (*instruction_handler)(DisasContext *dc, uint32_t opcode);
+
+typedef struct Nios2Instruction {
+    const char         *name;
+    instruction_handler handler;
+} Nios2Instruction;
+
+#define INSTRUCTION(name)    { stringify(name), name }
+#define INSTRUCTION_NOP(name)    { stringify(name), nop }
+#define INSTRUCTION_UNIMPLEMENTED(name)  { stringify(name), unimplemented }
+#define INSTRUCTION_ILLEGAL()  { "", illegal_instruction }
+
+extern void handle_instruction(DisasContext *dc, CPUNios2State *env);
+extern const char *instruction_get_string(uint32_t code);
+
+#define SIM_COMPAT 0
+#define DISAS_GNU 1   /* Disassembly via GNU gdb derived routines */
+#define DISAS_NIOS2 0 /* Disassembly via routines in instruction.c */
+#if DISAS_NIOS2 && !SIM_COMPAT
+#  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
+#else
+#  define LOG_DIS(...) do { } while (0)
+#endif
+
+#endif /* _INSTRUCTION_H_ */
diff --git a/target-nios2/machine.c b/target-nios2/machine.c
new file mode 100644
index 0000000..da2cb04
--- /dev/null
+++ b/target-nios2/machine.c
@@ -0,0 +1,38 @@
+/*
+ * Altera Nios II MMU emulation for qemu.
+ *
+ * Copyright (C) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+/*
+ * FIXME: Convert to VMstate
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/boards.h"
+
+void cpu_save(QEMUFile *f, void *opaque)
+{
+    /* TODO */
+}
+
+int cpu_load(QEMUFile *f, void *opaque, int version_id)
+{
+    /* TODO */
+    return 0;
+}
diff --git a/target-nios2/mmu.c b/target-nios2/mmu.c
new file mode 100644
index 0000000..fbb846a
--- /dev/null
+++ b/target-nios2/mmu.c
@@ -0,0 +1,292 @@
+/*
+ * Altera Nios II MMU emulation for qemu.
+ *
+ * Copyright (C) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "mmu.h"
+
+#if !defined(CONFIG_USER_ONLY)
+
+/* Define this to enable MMU debug messages */
+/* #define DEBUG_MMU */
+
+#ifdef DEBUG_MMU
+#define MMU_LOG(x) x
+#else
+#define MMU_LOG(x)
+#endif
+
+void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
+	      int mmu_idx, uintptr_t retaddr)
+{
+    int ret;
+
+    ret = nios2_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    if (unlikely(ret)) {
+        if (retaddr) {
+            /* now we have a real cpu fault */
+            cpu_restore_state(cs, retaddr);
+        }
+        cpu_loop_exit(cs);
+    }
+}
+
+uint32_t mmu_read(CPUNios2State *env, uint32_t rn)
+{
+    switch (rn) {
+    case CR_TLBACC:
+        MMU_LOG(qemu_log("TLBACC READ %08X\n", env->regs[rn]));
+        break;
+
+    case CR_TLBMISC:
+        MMU_LOG(qemu_log("TLBMISC READ %08X\n", env->regs[rn]));
+        break;
+
+    case CR_PTEADDR:
+        MMU_LOG(qemu_log("PTEADDR READ %08X\n", env->regs[rn]));
+        break;
+
+    default:
+        break;
+    }
+    return env->regs[rn];
+}
+
+/* rw - 0 = read, 1 = write, 2 = fetch.  */
+unsigned int mmu_translate(CPUNios2State *env,
+                           Nios2MMULookup *lu,
+                           target_ulong vaddr, int rw, int mmu_idx)
+{
+    int pid = (env->mmu.tlbmisc_wr & CR_TLBMISC_PID_MASK) >> 4;
+    int vpn = vaddr >> 12;
+
+    MMU_LOG(qemu_log("mmu_translate vaddr %08X, pid %08X, vpn %08X\n",
+                     vaddr, pid, vpn));
+
+    int way;
+    for (way = 0; way < env->mmu.tlb_num_ways; way++) {
+
+        Nios2TLBEntry *entry =
+            &env->mmu.tlb[(way * env->mmu.tlb_num_ways) +
+                          (vpn & env->mmu.tlb_entry_mask)];
+
+        MMU_LOG(qemu_log("TLB[%d] TAG %08X, VPN %08X\n",
+                         (way * env->mmu.tlb_num_ways) +
+                         (vpn & env->mmu.tlb_entry_mask),
+                         entry->tag, (entry->tag >> 12)));
+
+        if (((entry->tag >> 12) != vpn) ||
+            (((entry->tag & (1<<11)) == 0) &&
+            ((entry->tag & ((1<<env->mmu.pid_bits)-1)) != pid))) {
+            continue;
+        }
+        lu->vaddr = vaddr & TARGET_PAGE_MASK;
+        lu->paddr = (entry->data & CR_TLBACC_PFN_MASK) << TARGET_PAGE_BITS;
+        lu->prot = ((entry->data & CR_TLBACC_R) ? PAGE_READ : 0) |
+                   ((entry->data & CR_TLBACC_W) ? PAGE_WRITE : 0) |
+                   ((entry->data & CR_TLBACC_X) ? PAGE_EXEC : 0);
+
+        MMU_LOG(qemu_log("HIT TLB[%d] %08X %08X %08X\n",
+                         (way * env->mmu.tlb_num_ways) +
+                         (vpn & env->mmu.tlb_entry_mask),
+                         lu->vaddr, lu->paddr, lu->prot));
+        return 1;
+    }
+    return 0;
+}
+
+static void mmu_flush_pid(CPUNios2State *env, uint32_t pid)
+{
+    CPUState *cs = ENV_GET_CPU(env);
+    int idx;
+    MMU_LOG(qemu_log("TLB Flush PID %d\n", pid));
+
+    for (idx = 0; idx < env->mmu.tlb_num_entries; idx++) {
+        Nios2TLBEntry *entry = &env->mmu.tlb[idx];
+
+        MMU_LOG(qemu_log("TLB[%d] => %08X %08X\n",
+                         idx, entry->tag, entry->data));
+
+        if ((entry->tag & (1<<10)) && (!(entry->tag & (1<<11))) &&
+            ((entry->tag & ((1<<env->mmu.pid_bits)-1)) == pid)) {
+            uint32_t vaddr = entry->tag & TARGET_PAGE_MASK;
+
+            MMU_LOG(qemu_log("TLB Flush Page %08X\n", vaddr));
+
+            tlb_flush_page(cs, vaddr);
+        }
+    }
+}
+
+void mmu_write(CPUNios2State *env, uint32_t rn, uint32_t v)
+{
+    CPUState *cs = ENV_GET_CPU(env);
+
+    MMU_LOG(qemu_log("mmu_write %08X = %08X\n", rn, v));
+
+    switch (rn) {
+    case CR_TLBACC:
+        MMU_LOG(qemu_log("TLBACC: IG %02X, FLAGS %c%c%c%c%c, PFN %05X\n",
+                         v >> CR_TLBACC_IGN_SHIFT,
+                         (v & CR_TLBACC_C) ? 'C' : '.',
+                         (v & CR_TLBACC_R) ? 'R' : '.',
+                         (v & CR_TLBACC_W) ? 'W' : '.',
+                         (v & CR_TLBACC_X) ? 'X' : '.',
+                         (v & CR_TLBACC_G) ? 'G' : '.',
+                         v & CR_TLBACC_PFN_MASK));
+
+        /* if tlbmisc.WE == 1 then trigger a TLB write on writes to TLBACC */
+        if (env->regs[CR_TLBMISC] & CR_TLBMISC_WR) {
+            int way = (env->regs[CR_TLBMISC] >> CR_TLBMISC_WAY_SHIFT);
+            int vpn = (env->mmu.pteaddr_wr & CR_PTEADDR_VPN_MASK) >> 2;
+            int pid = (env->mmu.tlbmisc_wr & CR_TLBMISC_PID_MASK) >> 4;
+            int g = (v & CR_TLBACC_G) ? 1 : 0;
+            int valid = ((vpn & CR_TLBACC_PFN_MASK) < 0xC0000) ? 1 : 0;
+            Nios2TLBEntry *entry =
+                &env->mmu.tlb[(way * env->mmu.tlb_num_ways) +
+                              (vpn & env->mmu.tlb_entry_mask)];
+            uint32_t newTag = (vpn << 12) | (g << 11) | (valid << 10) | pid;
+            uint32_t newData = v & (CR_TLBACC_C | CR_TLBACC_R | CR_TLBACC_W |
+                                    CR_TLBACC_X | CR_TLBACC_PFN_MASK);
+
+            if ((entry->tag != newTag) || (entry->data != newData)) {
+                if (entry->tag & (1<<10)) {
+                    /* Flush existing entry */
+                    MMU_LOG(qemu_log("TLB Flush Page (OLD) %08X\n",
+                                     entry->tag & TARGET_PAGE_MASK));
+                    tlb_flush_page(cs, entry->tag & TARGET_PAGE_MASK);
+                }
+                entry->tag = newTag;
+                entry->data = newData;
+                MMU_LOG(qemu_log("TLB[%d] = %08X %08X\n",
+                                 (way * env->mmu.tlb_num_ways) +
+                                 (vpn & env->mmu.tlb_entry_mask),
+                                 entry->tag, entry->data));
+            }
+            /* Auto-increment tlbmisc.WAY */
+            env->regs[CR_TLBMISC] =
+                (env->regs[CR_TLBMISC] & ~CR_TLBMISC_WAY_MASK) |
+                (((way+1) & (env->mmu.tlb_num_ways-1)) << CR_TLBMISC_WAY_SHIFT);
+        }
+
+        /* Writes to TLBACC don't change the read-back value */
+        env->mmu.tlbacc_wr = v;
+        break;
+
+    case CR_TLBMISC:
+        MMU_LOG(qemu_log("TLBMISC: WAY %X, FLAGS %c%c%c%c%c%c, PID %04X\n",
+                         v >> CR_TLBMISC_WAY_SHIFT,
+                         (v & CR_TLBMISC_RD) ? 'R' : '.',
+                         (v & CR_TLBMISC_WR) ? 'W' : '.',
+                         (v & CR_TLBMISC_DBL) ? '2' : '.',
+                         (v & CR_TLBMISC_BAD) ? 'B' : '.',
+                         (v & CR_TLBMISC_PERM) ? 'P' : '.',
+                         (v & CR_TLBMISC_D) ? 'D' : '.',
+                         (v & CR_TLBMISC_PID_MASK) >> 4));
+
+        if ((v & CR_TLBMISC_PID_MASK) !=
+            (env->mmu.tlbmisc_wr & CR_TLBMISC_PID_MASK)) {
+            mmu_flush_pid(env, (env->mmu.tlbmisc_wr & CR_TLBMISC_PID_MASK) >>
+                               CR_TLBMISC_PID_SHIFT);
+        }
+        /* if tlbmisc.RD == 1 then trigger a TLB read on writes to TLBMISC */
+        if (v & CR_TLBMISC_RD) {
+            int way = (v >> CR_TLBMISC_WAY_SHIFT);
+            int vpn = (env->mmu.pteaddr_wr & CR_PTEADDR_VPN_MASK) >> 2;
+            Nios2TLBEntry *entry =
+                &env->mmu.tlb[(way * env->mmu.tlb_num_ways) +
+                              (vpn & env->mmu.tlb_entry_mask)];
+
+            env->regs[CR_TLBACC] &= CR_TLBACC_IGN_MASK;
+            env->regs[CR_TLBACC] |= entry->data |
+                                    ((entry->tag & (1<<11)) ? CR_TLBACC_G : 0);
+            env->regs[CR_TLBMISC] =
+                (v & ~CR_TLBMISC_PID_MASK) |
+                ((entry->tag & ((1<<env->mmu.pid_bits)-1)) <<
+                 CR_TLBMISC_PID_SHIFT);
+            env->regs[CR_PTEADDR] &= ~CR_PTEADDR_VPN_MASK;
+            env->regs[CR_PTEADDR] |= (entry->tag >> 12) << CR_PTEADDR_VPN_SHIFT;
+            MMU_LOG(qemu_log("TLB READ way %d, vpn %05X, tag %08X, data %08X, "
+                             "tlbacc %08X, tlbmisc %08X, pteaddr %08X\n",
+                             way, vpn, entry->tag, entry->data,
+                             env->regs[CR_TLBACC], env->regs[CR_TLBMISC],
+                             env->regs[CR_PTEADDR]));
+        } else {
+            env->regs[CR_TLBMISC] = v;
+        }
+
+        env->mmu.tlbmisc_wr = v;
+        break;
+
+    case CR_PTEADDR:
+        MMU_LOG(qemu_log("PTEADDR: PTBASE %03X, VPN %05X\n",
+                         v >> CR_PTEADDR_PTBASE_SHIFT,
+                         (v & CR_PTEADDR_VPN_MASK) >> CR_PTEADDR_VPN_SHIFT));
+
+        /* Writes to PTEADDR don't change the read-back VPN value */
+        env->regs[CR_PTEADDR] = (v & ~CR_PTEADDR_VPN_MASK) |
+                                (env->regs[CR_PTEADDR] & CR_PTEADDR_VPN_MASK);
+        env->mmu.pteaddr_wr = v;
+        break;
+
+    default:
+        break;
+    }
+}
+
+void mmu_init(Nios2MMU *mmu)
+{
+    MMU_LOG(qemu_log("mmu_init\n"));
+
+    mmu->pid_bits = 8;          /* TODO: get this from ALTR,pid-num-bits */
+    mmu->tlb_num_ways = 16;     /* TODO: get this from ALTR,tlb-num-ways */
+    mmu->tlb_num_entries = 256; /* TODO: get this from ALTR,tlb-num-entries */
+    mmu->tlb_entry_mask = (mmu->tlb_num_entries/mmu->tlb_num_ways) - 1;
+
+    mmu->tlb = (Nios2TLBEntry *)g_malloc0(
+        sizeof(Nios2TLBEntry) * mmu->tlb_num_entries);
+}
+
+void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUNios2State *env)
+{
+    int i;
+    cpu_fprintf(f, "MMU: ways %d, entries %d, pid bits %d\n",
+                env->mmu.tlb_num_ways, env->mmu.tlb_num_entries,
+                env->mmu.pid_bits);
+
+    for (i = 0; i < env->mmu.tlb_num_entries; i++) {
+        Nios2TLBEntry *entry = &env->mmu.tlb[i];
+        cpu_fprintf(f, "TLB[%d] = %08X %08X %c VPN %05X "
+                    "PID %02X %c PFN %05X %c%c%c%c\n",
+                    i, entry->tag, entry->data,
+                    (entry->tag & (1<<10)) ? 'V' : '-',
+                    entry->tag >> 12, entry->tag & ((1<<env->mmu.pid_bits)-1),
+                    (entry->tag & (1<<11)) ? 'G' : '-',
+                    entry->data & CR_TLBACC_PFN_MASK,
+                    (entry->data & CR_TLBACC_C) ? 'C' : '-',
+                    (entry->data & CR_TLBACC_R) ? 'R' : '-',
+                    (entry->data & CR_TLBACC_W) ? 'W' : '-',
+                    (entry->data & CR_TLBACC_X) ? 'X' : '-');
+    }
+}
+
+#endif /* !CONFIG_USER_ONLY */
diff --git a/target-nios2/mmu.h b/target-nios2/mmu.h
new file mode 100644
index 0000000..797db67
--- /dev/null
+++ b/target-nios2/mmu.h
@@ -0,0 +1,54 @@
+/*
+ * Altera Nios II MMU emulation for qemu.
+ *
+ * Copyright (C) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+#ifndef MMU_NIOS2_H
+#define MMU_NIOS2_H
+
+
+typedef struct Nios2TLBEntry {
+    target_ulong tag;
+    target_ulong data;
+} Nios2TLBEntry;
+
+typedef struct Nios2MMU {
+    int pid_bits;
+    int tlb_num_ways;
+    int tlb_num_entries;
+    int tlb_entry_mask;
+    uint32_t pteaddr_wr;
+    uint32_t tlbacc_wr;
+    uint32_t tlbmisc_wr;
+    Nios2TLBEntry *tlb;
+} Nios2MMU;
+
+typedef struct Nios2MMULookup {
+    target_ulong vaddr;
+    target_ulong paddr;
+    int prot;
+} Nios2MMULookup;
+
+void mmu_flip_um(CPUNios2State *env, unsigned int um);
+unsigned int mmu_translate(CPUNios2State *env,
+                           Nios2MMULookup *lu,
+                           target_ulong vaddr, int rw, int mmu_idx);
+uint32_t mmu_read(CPUNios2State *env, uint32_t rn);
+void mmu_write(CPUNios2State *env, uint32_t rn, uint32_t v);
+void mmu_init(Nios2MMU *mmu);
+
+#endif /* MMU_NIOS2_H */
diff --git a/target-nios2/monitor.c b/target-nios2/monitor.c
new file mode 100644
index 0000000..f3fa4cd
--- /dev/null
+++ b/target-nios2/monitor.c
@@ -0,0 +1,35 @@
+/*
+ * QEMU monitor
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "monitor/monitor.h"
+#include "monitor/hmp-target.h"
+#include "hmp.h"
+
+void hmp_info_tlb(Monitor *mon, const QDict *qdict)
+{
+    CPUArchState *env1 = mon_get_cpu_env();
+
+    dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1);
+}
diff --git a/target-nios2/op_helper.c b/target-nios2/op_helper.c
new file mode 100644
index 0000000..b8ef396
--- /dev/null
+++ b/target-nios2/op_helper.c
@@ -0,0 +1,86 @@
+/*
+ * Altera Nios II helper routines.
+ *
+ * Copyright (C) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "cpu.h"
+#include "exec/helper-proto.h"
+#include "exec/cpu_ldst.h"
+
+#if !defined(CONFIG_USER_ONLY)
+uint32_t helper_mmu_read(CPUNios2State *env, uint32_t rn)
+{
+    return mmu_read(env, rn);
+}
+
+void helper_mmu_write(CPUNios2State *env, uint32_t rn, uint32_t v)
+{
+    mmu_write(env, rn, v);
+}
+
+void helper_check_interrupts(CPUNios2State *env)
+{
+    nios2_check_interrupts(env);
+}
+#endif /* !CONFIG_USER_ONLY */
+
+void helper_raise_exception(CPUNios2State *env, uint32_t index)
+{
+    CPUState *cs = ENV_GET_CPU(env);
+    cs->exception_index = index;
+    cpu_loop_exit(cs);
+}
+
+void helper_memalign(CPUNios2State *env, uint32_t addr, uint32_t dr, uint32_t wr, uint32_t mask)
+{
+    if (addr & mask) {
+        qemu_log("unaligned access addr=%x mask=%x, wr=%d dr=r%d\n",
+                 addr, mask, wr, dr);
+        env->regs[CR_BADADDR] = addr;
+        env->regs[CR_EXCEPTION] = EXCP_UNALIGN << 2;
+        helper_raise_exception(env, EXCP_UNALIGN);
+    }
+}
+
+uint32_t helper_divs(uint32_t a, uint32_t b)
+{
+    return (int32_t)a / (int32_t)b;
+}
+
+uint32_t helper_divu(uint32_t a, uint32_t b)
+{
+    return a / b;
+}
+
+#ifdef CALL_TRACING
+void helper_call_status(uint32_t pc, uint32_t target)
+{
+    qemu_log("%08X: CALL %08X %s\n", pc, target, lookup_symbol(target));
+}
+
+void helper_eret_status(uint32_t pc)
+{
+    qemu_log("%08X: ERET STATUS %08X, ESTATUS %08X, EA %08X\n",
+             pc, env->regs[CR_STATUS], env->regs[CR_ESTATUS], env->regs[R_EA]);
+}
+
+void helper_ret_status(uint32_t pc)
+{
+    qemu_log("%08X: RET RA %08X\n", pc, env->regs[R_RA]);
+}
+#endif
diff --git a/target-nios2/translate.c b/target-nios2/translate.c
new file mode 100644
index 0000000..16d1df8
--- /dev/null
+++ b/target-nios2/translate.c
@@ -0,0 +1,242 @@
+/*
+ * Altera Nios II emulation for qemu: main translation routines.
+ *
+ * Copyright (C) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <assert.h>
+
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "disas/disas.h"
+#include "exec/helper-proto.h"
+#include "qemu-common.h"
+
+#include "instruction.h"
+
+#include "exec/cpu_ldst.h"
+#include "exec/helper-gen.h"
+#include "exec/log.h"
+
+static const char *regnames[] = {
+    "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",
+    "status",   "estatus",  "bstatus",  "ienable",
+    "ipending", "cpuid",    "reserved", "exception",
+    "pteaddr",  "tlbacc",   "tlbmisc",  "reserved",
+    "badaddr",  "config",   "mpubase",  "mpuacc",
+    "reserved", "reserved", "reserved", "reserved",
+    "reserved", "reserved", "reserved", "reserved",
+    "reserved", "reserved", "reserved", "reserved",
+    "reserved", "reserved", "reserved", "reserved",
+    "rpc"
+};
+
+static TCGv_ptr cpu_env;
+static TCGv cpu_R[NUM_CORE_REGS];
+
+#include "exec/gen-icount.h"
+
+static void gen_exception(DisasContext *dc, uint32_t excp)
+{
+    TCGv_i32 tmp = tcg_const_i32(excp);
+
+    tcg_gen_movi_tl(cpu_R[R_PC], dc->pc);
+    gen_helper_raise_exception(cpu_env, tmp);
+    tcg_temp_free_i32(tmp);
+    dc->is_jmp = DISAS_UPDATE;
+}
+
+/* generate intermediate code for basic block 'tb'.  */
+void gen_intermediate_code(CPUNios2State *env, TranslationBlock *tb)
+{
+    Nios2CPU *cpu = nios2_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
+    DisasContext dc1, *dc = &dc1;
+    int num_insns;
+    int max_insns;
+    uint32_t next_page_start;
+
+    /* Initialize DC */
+    dc->cpu_env = cpu_env;
+    dc->cpu_R   = cpu_R;
+    dc->is_jmp  = DISAS_NEXT;
+    dc->pc      = tb->pc;
+    dc->tb      = tb;
+    dc->mem_idx = cpu_mmu_index(env, false);
+
+    /* Dump the CPU state to the log */
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+        qemu_log("--------------\n");
+        log_cpu_state(cs, 0);
+    }
+
+    /* Set up instruction counts */
+    num_insns = 0;
+    max_insns = tb->cflags & CF_COUNT_MASK;
+    if (max_insns == 0) {
+        max_insns = CF_COUNT_MASK;
+    }
+    if (max_insns > TCG_MAX_INSNS) {
+        max_insns = TCG_MAX_INSNS;
+    }
+    next_page_start = (tb->pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
+
+    gen_tb_start(tb);
+    do {
+        LOG_DIS("%8.8x:\t", dc->pc);
+
+        tcg_gen_insn_start(dc->pc);
+        num_insns++;
+
+#if SIM_COMPAT
+        if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+            tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
+            gen_helper_debug();
+        }
+#endif
+
+        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
+            gen_exception(dc, EXCP_DEBUG);
+            /* The address covered by the breakpoint must be included in
+               [tb->pc, tb->pc + tb->size) in order to for it to be
+               properly cleared -- thus we increment the PC here so that
+               the logic setting tb->size below does the right thing.  */
+            dc->pc += 4;
+            break;
+        }
+
+        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
+            gen_io_start();
+        }
+
+        /* Decode an instruction */
+        handle_instruction(dc, env);
+
+        dc->pc += 4;
+
+        /* Translation stops when a conditional branch is encountered.
+         * Otherwise the subsequent code could get translated several times.
+         * Also stop translation when a page boundary is reached.  This
+         * ensures prefetch aborts occur at the right place.  */
+    } while (!dc->is_jmp &&
+             !tcg_op_buf_full() &&
+             !cs->singlestep_enabled &&
+             !singlestep &&
+             dc->pc < next_page_start &&
+             num_insns < max_insns);
+
+    if (tb->cflags & CF_LAST_IO) {
+        gen_io_end();
+    }
+
+    /* Indicate where the next block should start */
+    switch (dc->is_jmp) {
+    case DISAS_NEXT:
+        /* Save the current PC back into the CPU register */
+        tcg_gen_movi_tl(cpu_R[R_PC], dc->pc);
+        tcg_gen_exit_tb(0);
+        break;
+
+    default:
+    case DISAS_JUMP:
+    case DISAS_UPDATE:
+        /* The jump will already have updated the PC register */
+        tcg_gen_exit_tb(0);
+        break;
+
+    case DISAS_TB_JUMP:
+        /* nothing more to generate */
+        break;
+    }
+
+    /* End off the block */
+    gen_tb_end(tb, num_insns);
+
+    /* Mark instruction starts for the final generated instruction */
+    tb->size = dc->pc - tb->pc;
+    tb->icount = num_insns;
+
+#ifdef DEBUG_DISAS
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+        qemu_log("----------------\n");
+        qemu_log("IN: %s\n", lookup_symbol(tb->pc));
+        log_target_disas(cs, tb->pc, dc->pc - tb->pc, 0);
+        qemu_log("\nisize=%d osize=%d\n",
+                 dc->pc - tb->pc, tcg_op_buf_count());
+    }
+#endif
+}
+
+void nios2_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                          int flags)
+{
+    Nios2CPU *cpu = NIOS2_CPU(cs);
+    CPUNios2State *env = &cpu->env;
+    int i;
+
+    if (!env || !f) {
+        return;
+    }
+
+    cpu_fprintf(f, "IN: PC=%x %s\n",
+                env->regs[R_PC], lookup_symbol(env->regs[R_PC]));
+
+    for (i = 0; i < NUM_CORE_REGS; i++) {
+        cpu_fprintf(f, "%9s=%8.8x ", regnames[i], env->regs[i]);
+        if ((i + 1) % 4 == 0) {
+            cpu_fprintf(f, "\n");
+        }
+    }
+#if !defined(CONFIG_USER_ONLY)
+    cpu_fprintf(f, " mmu write: VPN=%05X PID %02X TLBACC %08X\n",
+                env->mmu.pteaddr_wr & CR_PTEADDR_VPN_MASK,
+                (env->mmu.tlbmisc_wr & CR_TLBMISC_PID_MASK) >> 4,
+                env->mmu.tlbacc_wr);
+#endif
+    cpu_fprintf(f, "\n\n");
+}
+
+void nios2_tcg_init(void)
+{
+    int i;
+
+    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+
+    for (i = 0; i < NUM_CORE_REGS; i++) {
+        cpu_R[i] = tcg_global_mem_new(cpu_env,
+                                      offsetof(CPUNios2State, regs[i]),
+                                      regnames[i]);
+    }
+}
+
+void restore_state_to_opc(CPUNios2State *env, TranslationBlock *tb,
+                          target_ulong *data)
+{
+    env->regs[R_PC] = data[0];
+}
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 3/7] nios2: Add usermode binaries emulation
  2016-09-27 23:30 [Qemu-devel] [PATCH V2 1/7] nios2: Add disas entries Marek Vasut
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support Marek Vasut
@ 2016-09-27 23:30 ` Marek Vasut
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 4/7] nios2: Add IIC interrupt controller emulation Marek Vasut
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2016-09-27 23:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marek Vasut, Chris Wulff, Jeff Da Silva, Ley Foon Tan,
	Sandra Loosemore, Yves Vandervennet

Add missing bits for qemu-user required for emulating Altera Nios2
userspace binaries.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Chris Wulff <crwulff@gmail.com>
Cc: Jeff Da Silva <jdasilva@altera.com>
Cc: Ley Foon Tan <lftan@altera.com>
Cc: Sandra Loosemore <sandra@codesourcery.com>
Cc: Yves Vandervennet <yvanderv@altera.com>
---
 include/elf.h                     |   2 +
 linux-user/elfload.c              |  58 +++++++
 linux-user/main.c                 | 136 +++++++++++++++-
 linux-user/nios2/syscall_nr.h     | 330 ++++++++++++++++++++++++++++++++++++++
 linux-user/nios2/target_cpu.h     |  38 +++++
 linux-user/nios2/target_signal.h  |  26 +++
 linux-user/nios2/target_structs.h |  58 +++++++
 linux-user/nios2/target_syscall.h |  37 +++++
 linux-user/nios2/termbits.h       | 220 +++++++++++++++++++++++++
 linux-user/signal.c               | 237 ++++++++++++++++++++++++++-
 linux-user/syscall_defs.h         |   7 +-
 11 files changed, 1142 insertions(+), 7 deletions(-)
 create mode 100644 linux-user/nios2/syscall_nr.h
 create mode 100644 linux-user/nios2/target_cpu.h
 create mode 100644 linux-user/nios2/target_signal.h
 create mode 100644 linux-user/nios2/target_structs.h
 create mode 100644 linux-user/nios2/target_syscall.h
 create mode 100644 linux-user/nios2/termbits.h

diff --git a/include/elf.h b/include/elf.h
index 1c2975d..0dbd3e9 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -126,6 +126,8 @@ typedef int64_t  Elf64_Sxword;
  */
 #define EM_S390_OLD     0xA390
 
+#define EM_ALTERA_NIOS2 113     /* Altera Nios II soft-core processor */
+
 #define EM_MICROBLAZE      189
 #define EM_MICROBLAZE_OLD  0xBAAB
 
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 816272a..b610ad4 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -967,6 +967,64 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMBState *env
 
 #endif /* TARGET_MICROBLAZE */
 
+#ifdef TARGET_NIOS2
+
+#define ELF_START_MMAP 0x80000000
+
+#define elf_check_arch(x) ((x) == EM_ALTERA_NIOS2)
+
+#define ELF_CLASS   ELFCLASS32
+#define ELF_ARCH    EM_ALTERA_NIOS2
+
+static inline void init_thread(struct target_pt_regs *regs,
+                               struct image_info *infop)
+{
+    regs->ea = infop->entry;
+    regs->sp = infop->start_stack;
+    regs->estatus = 0x3;
+}
+
+#define ELF_EXEC_PAGESIZE        4096
+
+#define USE_ELF_CORE_DUMP
+#define ELF_NREG 49
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+/* See linux kernel: arch/mips/kernel/process.c:elf_dump_regs.  */
+static void elf_core_copy_regs(target_elf_gregset_t *regs,
+			       const CPUNios2State *env)
+{
+    int i;
+
+    (*regs)[0] = -1;
+    for (i = 1; i < 8; i++)	/* r0-r7 */
+        (*regs)[i] = tswapreg(env->regs[i + 7]);
+
+    for (i = 8; i < 16; i++)	/* r8-r15 */
+        (*regs)[i] = tswapreg(env->regs[i - 8]);
+
+    for (i = 16; i < 24; i++)	/* r16-r23 */
+        (*regs)[i] = tswapreg(env->regs[i + 7]);
+    (*regs)[24] = -1;	/* R_ET */
+    (*regs)[25] = -1;	/* R_BT */
+    (*regs)[26] = tswapreg(env->regs[R_GP]);
+    (*regs)[27] = tswapreg(env->regs[R_SP]);
+    (*regs)[28] = tswapreg(env->regs[R_FP]);
+    (*regs)[29] = tswapreg(env->regs[R_EA]);
+    (*regs)[30] = -1;	/* R_SSTATUS */
+    (*regs)[31] = tswapreg(env->regs[R_RA]);
+
+    (*regs)[32] = tswapreg(env->regs[R_PC]);
+
+    (*regs)[33] = -1; /* R_STATUS */
+    (*regs)[34] = tswapreg(env->regs[CR_ESTATUS]);
+
+    for (i = 35; i < 49; i++)	/* ... */
+	    (*regs)[i] = -1;
+}
+
+#endif /* TARGET_NIOS2 */
+
 #ifdef TARGET_OPENRISC
 
 #define ELF_START_MMAP 0x08000000
diff --git a/linux-user/main.c b/linux-user/main.c
index 8daebe0..0bdf6e5 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -68,8 +68,11 @@ do {                                                                    \
  * This way we will never overlap with our own libraries or binaries or stack
  * or anything else that QEMU maps.
  */
-# ifdef TARGET_MIPS
-/* MIPS only supports 31 bits of virtual address space for user space */
+# if defined(TARGET_MIPS) || defined(TARGET_NIOS2)
+/*
+ * MIPS only supports 31 bits of virtual address space for user space.
+ * Nios2 also only supports 31 bits.
+ */
 unsigned long reserved_va = 0x77000000;
 # else
 unsigned long reserved_va = 0xf7000000;
@@ -2712,6 +2715,105 @@ error:
 }
 #endif
 
+#ifdef TARGET_NIOS2
+
+void cpu_loop(CPUNios2State *env)
+{
+    CPUState *cs = ENV_GET_CPU(env);
+    target_siginfo_t info;
+    int trapnr, gdbsig, ret;
+
+    for (;;) {
+        cpu_exec_start(cs);
+        trapnr = cpu_exec(cs);
+        cpu_exec_end(cs);
+        gdbsig = 0;
+
+        switch (trapnr) {
+        case EXCP_INTERRUPT:
+            /* just indicate that signals should be handled asap */
+            break;
+        case EXCP_TRAP:
+            if (env->regs[R_AT] == 0) {
+                abi_long ret;
+                qemu_log_mask(CPU_LOG_INT, "\nSyscall\n");
+
+                ret = do_syscall(env, env->regs[2],
+                                 env->regs[4], env->regs[5], env->regs[6],
+                                 env->regs[7], env->regs[8], env->regs[9],
+                                 0, 0);
+
+		if (env->regs[2] == 0)	/* FIXME: syscall 0 workaround */
+			ret = 0;
+
+                env->regs[2] = abs(ret);
+		/* Return value is 0..4096 */
+                env->regs[7] = (ret > 0xfffffffffffff000ULL);
+                env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
+                env->regs[CR_STATUS] &= ~0x3;
+                env->regs[R_EA] = env->regs[R_PC] + 4;
+                env->regs[R_PC] += 4;
+		break;
+            } else {
+                qemu_log_mask(CPU_LOG_INT, "\nTrap\n");
+
+                env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
+                env->regs[CR_STATUS] &= ~0x3;
+                env->regs[R_EA] = env->regs[R_PC] + 4;
+                env->regs[R_PC] = env->exception_addr;
+
+                gdbsig = TARGET_SIGTRAP;
+                break;
+            }
+        case 0xaa:
+            switch (env->regs[R_PC]) {
+                //case 0x1000:	/* __kuser_helper_version */
+		case 0x1004:	/* __kuser_cmpxchg */
+                    start_exclusive();
+		    if (env->regs[4] & 0x3)
+		        goto kuser_fail;
+                    ret = get_user_u32(env->regs[2], env->regs[4]);
+                    if (ret) {
+                        end_exclusive();
+                        goto kuser_fail;
+                    }
+                    env->regs[2] -= env->regs[5];
+                    if (env->regs[2] == 0) {
+                        put_user_u32(env->regs[6], env->regs[4]);
+                    }
+                    end_exclusive();
+                    env->regs[R_PC] = env->regs[R_RA];
+                    break;
+                    //case 0x1040:	/* __kuser_sigtramp */
+kuser_fail:
+                default:
+                    info.si_signo = TARGET_SIGSEGV;
+                    info.si_errno = 0;
+                    /* XXX: check env->error_code */
+                    info.si_code = TARGET_SEGV_MAPERR;
+                    info._sifields._sigfault._addr = env->regs[R_PC];
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+            }
+	    break;
+        default:
+            EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
+                     trapnr);
+            gdbsig = TARGET_SIGILL;
+            break;
+        }
+        if (gdbsig) {
+            gdb_handlesig(cs, gdbsig);
+            if (gdbsig != TARGET_SIGTRAP) {
+                exit(EXIT_FAILURE);
+            }
+        }
+
+        process_pending_signals(env);
+    }
+}
+
+#endif /* TARGET_NIOS2 */
+
 #ifdef TARGET_OPENRISC
 
 void cpu_loop(CPUOpenRISCState *env)
@@ -4711,6 +4813,36 @@ int main(int argc, char **argv, char **envp)
             restore_snan_bit_mode(env);
         }
     }
+#elif defined(TARGET_NIOS2)
+    {
+	env->regs[0] = 0;
+	env->regs[1] = regs->r1;
+	env->regs[2] = regs->r2;
+	env->regs[3] = regs->r3;
+	env->regs[4] = regs->r4;
+	env->regs[5] = regs->r5;
+	env->regs[6] = regs->r6;
+	env->regs[7] = regs->r7;
+	env->regs[8] = regs->r8;
+	env->regs[9] = regs->r9;
+	env->regs[10] = regs->r10;
+	env->regs[11] = regs->r11;
+	env->regs[12] = regs->r12;
+	env->regs[13] = regs->r13;
+	env->regs[14] = regs->r14;
+	env->regs[15] = regs->r15;
+	// unsigned long  orig_r2;
+	env->regs[R_RA] = regs->ra;
+	env->regs[R_FP] = regs->fp;
+	env->regs[R_SP] = regs->sp;
+	env->regs[R_GP] = regs->gp;
+	env->regs[CR_ESTATUS] = regs->estatus;
+	env->regs[R_EA] = regs->ea;
+	// unsigned long  orig_r7;
+
+	/* Emulate eret when starting thread. */
+	env->regs[R_PC] = regs->ea;
+    }
 #elif defined(TARGET_OPENRISC)
     {
         int i;
diff --git a/linux-user/nios2/syscall_nr.h b/linux-user/nios2/syscall_nr.h
new file mode 100644
index 0000000..0939d43
--- /dev/null
+++ b/linux-user/nios2/syscall_nr.h
@@ -0,0 +1,330 @@
+#define TARGET_NR_io_setup			0
+#define TARGET_NR_io_destroy			1
+#define TARGET_NR_io_submit			2
+#define TARGET_NR_io_cancel			3
+#define TARGET_NR_io_getevents			4
+#define TARGET_NR_setxattr			5
+#define TARGET_NR_lsetxattr			6
+#define TARGET_NR_fsetxattr			7
+#define TARGET_NR_getxattr			8
+#define TARGET_NR_lgetxattr			9
+#define TARGET_NR_fgetxattr			10
+#define TARGET_NR_listxattr			11
+#define TARGET_NR_llistxattr			12
+#define TARGET_NR_flistxattr			13
+#define TARGET_NR_removexattr			14
+#define TARGET_NR_lremovexattr			15
+#define TARGET_NR_fremovexattr			16
+#define TARGET_NR_getcwd			17
+#define TARGET_NR_lookup_dcookie		18
+#define TARGET_NR_eventfd2			19
+#define TARGET_NR_epoll_create1			20
+#define TARGET_NR_epoll_ctl			21
+#define TARGET_NR_epoll_pwait			22
+#define TARGET_NR_dup				23
+#define TARGET_NR_dup3				24
+#define TARGET_NR_fcntl64			25
+#define TARGET_NR_inotify_init1			26
+#define TARGET_NR_inotify_add_watch		27
+#define TARGET_NR_inotify_rm_watch		28
+#define TARGET_NR_ioctl				29
+#define TARGET_NR_ioprio_set			30
+#define TARGET_NR_ioprio_get			31
+#define TARGET_NR_flock				32
+#define TARGET_NR_mknodat			33
+#define TARGET_NR_mkdirat			34
+#define TARGET_NR_unlinkat			35
+#define TARGET_NR_symlinkat			36
+#define TARGET_NR_linkat			37
+#define TARGET_NR_renameat			38
+#define TARGET_NR_umount2			39
+#define TARGET_NR_mount				40
+#define TARGET_NR_pivot_root			41
+#define TARGET_NR_nfsservctl			42
+#define TARGET_NR_statfs64			43
+#define TARGET_NR_fstatfs64			44
+#define TARGET_NR_truncate64			45
+#define TARGET_NR_ftruncate64			46
+#define TARGET_NR_fallocate			47
+#define TARGET_NR_faccessat			48
+#define TARGET_NR_chdir				49
+#define TARGET_NR_fchdir			50
+#define TARGET_NR_chroot			51
+#define TARGET_NR_fchmod			52
+#define TARGET_NR_fchmodat			53
+#define TARGET_NR_fchownat			54
+#define TARGET_NR_fchown			55
+#define TARGET_NR_openat			56
+#define TARGET_NR_close				57
+#define TARGET_NR_vhangup			58
+#define TARGET_NR_pipe2				59
+#define TARGET_NR_quotactl			60
+#define TARGET_NR_getdents64			61
+#define TARGET_NR_read				63
+#define TARGET_NR_write				64
+#define TARGET_NR_readv				65
+#define TARGET_NR_writev			66
+#define TARGET_NR_pread64			67
+#define TARGET_NR_pwrite64			68
+#define TARGET_NR_preadv			69
+#define TARGET_NR_pwritev			70
+#define TARGET_NR_sendfile64			71
+#define TARGET_NR_pselect6			72
+#define TARGET_NR_ppoll				73
+#define TARGET_NR_signalfd4			74
+#define TARGET_NR_vmsplice			75
+#define TARGET_NR_splice			76
+#define TARGET_NR_tee				77
+#define TARGET_NR_readlinkat			78
+#define TARGET_NR_fstatat64			79
+#define TARGET_NR_fstat64			80
+#define TARGET_NR_sync				81
+#define TARGET_NR_fsync				82
+#define TARGET_NR_fdatasync			83
+#define TARGET_NR_sync_file_range		84
+#define TARGET_NR_timerfd_create		85
+#define TARGET_NR_timerfd_settime		86
+#define TARGET_NR_timerfd_gettime		87
+#define TARGET_NR_utimensat			88
+#define TARGET_NR_acct				89
+#define TARGET_NR_capget			90
+#define TARGET_NR_capset			91
+#define TARGET_NR_personality			92
+#define TARGET_NR_exit				93
+#define TARGET_NR_exit_group			94
+#define TARGET_NR_waitid			95
+#define TARGET_NR_set_tid_address		96
+#define TARGET_NR_unshare			97
+#define TARGET_NR_futex				98
+#define TARGET_NR_set_robust_list		99
+#define TARGET_NR_get_robust_list		100
+#define TARGET_NR_nanosleep			101
+#define TARGET_NR_getitimer			102
+#define TARGET_NR_setitimer			103
+#define TARGET_NR_kexec_load			104
+#define TARGET_NR_init_module			105
+#define TARGET_NR_delete_module			106
+#define TARGET_NR_timer_create			107
+#define TARGET_NR_timer_gettime			108
+#define TARGET_NR_timer_getoverrun		109
+#define TARGET_NR_timer_settime			110
+#define TARGET_NR_timer_delete			111
+#define TARGET_NR_clock_settime			112
+#define TARGET_NR_clock_gettime			113
+#define TARGET_NR_clock_getres			114
+#define TARGET_NR_clock_nanosleep		115
+#define TARGET_NR_syslog			116
+#define TARGET_NR_ptrace			117
+#define TARGET_NR_sched_setparam		118
+#define TARGET_NR_sched_setscheduler		119
+#define TARGET_NR_sched_getscheduler		120
+#define TARGET_NR_sched_getparam		121
+#define TARGET_NR_sched_setaffinity		122
+#define TARGET_NR_sched_getaffinity		123
+#define TARGET_NR_sched_yield			124
+#define TARGET_NR_sched_get_priority_max	125
+#define TARGET_NR_sched_get_priority_min	126
+#define TARGET_NR_sched_rr_get_interval		127
+#define TARGET_NR_restart_syscall		128
+#define TARGET_NR_kill				129
+#define TARGET_NR_tkill				130
+#define TARGET_NR_tgkill			131
+#define TARGET_NR_sigaltstack			132
+#define TARGET_NR_rt_sigsuspend			133
+#define TARGET_NR_rt_sigaction			134
+#define TARGET_NR_rt_sigprocmask		135
+#define TARGET_NR_rt_sigpending			136
+#define TARGET_NR_rt_sigtimedwait		137
+#define TARGET_NR_rt_sigqueueinfo		138
+#define TARGET_NR_rt_sigreturn			139
+#define TARGET_NR_setpriority			140
+#define TARGET_NR_getpriority			141
+#define TARGET_NR_reboot			142
+#define TARGET_NR_setregid			143
+#define TARGET_NR_setgid			144
+#define TARGET_NR_setreuid			145
+#define TARGET_NR_setuid			146
+#define TARGET_NR_setresuid			147
+#define TARGET_NR_getresuid			148
+#define TARGET_NR_setresgid			149
+#define TARGET_NR_getresgid			150
+#define TARGET_NR_setfsuid			151
+#define TARGET_NR_setfsgid			152
+#define TARGET_NR_times				153
+#define TARGET_NR_setpgid			154
+#define TARGET_NR_getpgid			155
+#define TARGET_NR_getsid			156
+#define TARGET_NR_setsid			157
+#define TARGET_NR_getgroups			158
+#define TARGET_NR_setgroups			159
+#define TARGET_NR_uname				160
+#define TARGET_NR_sethostname			161
+#define TARGET_NR_setdomainname			162
+#define TARGET_NR_getrlimit			163
+#define TARGET_NR_setrlimit			164
+#define TARGET_NR_getrusage			165
+#define TARGET_NR_umask				166
+#define TARGET_NR_prctl				167
+#define TARGET_NR_getcpu			168
+#define TARGET_NR_gettimeofday			169
+#define TARGET_NR_settimeofday			170
+#define TARGET_NR_adjtimex			171
+#define TARGET_NR_getpid			172
+#define TARGET_NR_getppid			173
+#define TARGET_NR_getuid			174
+#define TARGET_NR_geteuid			175
+#define TARGET_NR_getgid			176
+#define TARGET_NR_getegid			177
+#define TARGET_NR_gettid			178
+#define TARGET_NR_sysinfo			179
+#define TARGET_NR_mq_open			180
+#define TARGET_NR_mq_unlink			181
+#define TARGET_NR_mq_timedsend			182
+#define TARGET_NR_mq_timedreceive		183
+#define TARGET_NR_mq_notify			184
+#define TARGET_NR_mq_getsetattr			185
+#define TARGET_NR_msgget			186
+#define TARGET_NR_msgctl			187
+#define TARGET_NR_msgrcv			188
+#define TARGET_NR_msgsnd			189
+#define TARGET_NR_semget			190
+#define TARGET_NR_semctl			191
+#define TARGET_NR_semtimedop			192
+#define TARGET_NR_semop				193
+#define TARGET_NR_shmget			194
+#define TARGET_NR_shmctl			195
+#define TARGET_NR_shmat				196
+#define TARGET_NR_shmdt				197
+#define TARGET_NR_socket			198
+#define TARGET_NR_socketpair			199
+#define TARGET_NR_bind				200
+#define TARGET_NR_listen			201
+#define TARGET_NR_accept			202
+#define TARGET_NR_connect			203
+#define TARGET_NR_getsockname			204
+#define TARGET_NR_getpeername			205
+#define TARGET_NR_sendto			206
+#define TARGET_NR_recvfrom			207
+#define TARGET_NR_setsockopt			208
+#define TARGET_NR_getsockopt			209
+#define TARGET_NR_shutdown			210
+#define TARGET_NR_sendmsg			211
+#define TARGET_NR_recvmsg			212
+#define TARGET_NR_readahead			213
+#define TARGET_NR_brk				214
+#define TARGET_NR_munmap			215
+#define TARGET_NR_mremap			216
+#define TARGET_NR_add_key			217
+#define TARGET_NR_request_key			218
+#define TARGET_NR_keyctl			219
+#define TARGET_NR_clone				220
+#define TARGET_NR_execve			221
+#define TARGET_NR_mmap2				222
+#define TARGET_NR_fadvise64_64			223
+#define TARGET_NR_swapon			224
+#define TARGET_NR_swapoff			225
+#define TARGET_NR_mprotect			226
+#define TARGET_NR_msync				227
+#define TARGET_NR_mlock				228
+#define TARGET_NR_munlock			229
+#define TARGET_NR_mlockall			230
+#define TARGET_NR_munlockall			231
+#define TARGET_NR_mincore			232
+#define TARGET_NR_madvise			233
+#define TARGET_NR_remap_file_pages		234
+#define TARGET_NR_mbind				235
+#define TARGET_NR_get_mempolicy			236
+#define TARGET_NR_set_mempolicy			237
+#define TARGET_NR_migrate_pages			238
+#define TARGET_NR_move_pages			239
+#define TARGET_NR_rt_tgsigqueueinfo		240
+#define TARGET_NR_perf_event_open		241
+#define TARGET_NR_accept4			242
+#define TARGET_NR_recvmmsg			243
+#define TARGET_NR_cacheflush			244
+#define TARGET_NR_arch_specific_syscall		244
+#define TARGET_NR_wait4				260
+#define TARGET_NR_prlimit64			261
+#define TARGET_NR_fanotify_init			262
+#define TARGET_NR_fanotify_mark			263
+#define TARGET_NR_name_to_handle_at		264
+#define TARGET_NR_open_by_handle_at		265
+#define TARGET_NR_clock_adjtime			266
+#define TARGET_NR_syncfs			267
+#define TARGET_NR_setns				268
+#define TARGET_NR_sendmmsg			269
+#define TARGET_NR_process_vm_readv		270
+#define TARGET_NR_process_vm_writev		271
+#define TARGET_NR_kcmp				272
+#define TARGET_NR_finit_module			273
+#define TARGET_NR_sched_setattr			274
+#define TARGET_NR_sched_getattr			275
+#define TARGET_NR_renameat2			276
+#define TARGET_NR_seccomp			277
+#define TARGET_NR_getrandom			278
+#define TARGET_NR_memfd_create			279
+#define TARGET_NR_bpf				280
+#define TARGET_NR_execveat			281
+#define TARGET_NR_userfaultfd			282
+#define TARGET_NR_membarrier			283
+#define TARGET_NR_mlock2			284
+#define TARGET_NR_copy_file_range		285
+#define TARGET_NR_preadv2			286
+#define TARGET_NR_pwritev2			287
+/* FIXME */
+#define TARGET_NR_open 1024
+#define TARGET_NR_link 1025
+#define TARGET_NR_unlink 1026
+#define TARGET_NR_mknod 1027
+#define TARGET_NR_chmod 1028
+#define TARGET_NR_chown 1029
+#define TARGET_NR_mkdir 1030
+#define TARGET_NR_rmdir 1031
+#define TARGET_NR_lchown 1032
+#define TARGET_NR_access 1033
+#define TARGET_NR_rename 1034
+#define TARGET_NR_readlink 1035
+#define TARGET_NR_symlink 1036
+#define TARGET_NR_utimes 1037
+#define TARGET_NR_3264_stat 1038
+#define TARGET_NR_3264_lstat 1039
+#define TARGET_NR_pipe 1040
+#define TARGET_NR_dup2 1041
+#define TARGET_NR_epoll_create 1042
+#define TARGET_NR_inotify_init 1043
+#define TARGET_NR_eventfd 1044
+#define TARGET_NR_signalfd 1045
+#define TARGET_NR_sendfile 1046
+#define TARGET_NR_ftruncate 1047
+#define TARGET_NR_truncate 1048
+#define TARGET_NR_stat 1049
+#define TARGET_NR_lstat 1050
+#define TARGET_NR_fstat 1051
+#define TARGET_NR_fcntl 1052
+#define TARGET_NR_fadvise64 1053
+#define TARGET_NR_newfstatat 1054
+#define TARGET_NR_fstatfs 1055
+#define TARGET_NR_statfs 1056
+#define TARGET_NR_lseek 1057
+#define TARGET_NR_mmap 1058
+#define TARGET_NR_alarm 1059
+#define TARGET_NR_getpgrp 1060
+#define TARGET_NR_pause 1061
+#define TARGET_NR_time 1062
+#define TARGET_NR_utime 1063
+#define TARGET_NR_creat 1064
+#define TARGET_NR_getdents 1065
+#define TARGET_NR_futimesat 1066
+#define TARGET_NR_select 1067
+#define TARGET_NR_poll 1068
+#define TARGET_NR_epoll_wait 1069
+#define TARGET_NR_ustat 1070
+#define TARGET_NR_vfork 1071
+#define TARGET_NR_oldwait4 1072
+#define TARGET_NR_recv 1073
+#define TARGET_NR_send 1074
+#define TARGET_NR_bdflush 1075
+#define TARGET_NR_umount 1076
+#define TARGET_NR_uselib 1077
+#define TARGET_NR__sysctl 1078
+#define TARGET_NR_fork 1079
diff --git a/linux-user/nios2/target_cpu.h b/linux-user/nios2/target_cpu.h
new file mode 100644
index 0000000..5b1e195
--- /dev/null
+++ b/linux-user/nios2/target_cpu.h
@@ -0,0 +1,38 @@
+/*
+ * Nios2 specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2016 Marek Vasut <marex@denx.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUNios2State *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->regs[R_SP] = newsp;
+    }
+    env->regs[R_RET0] = 0;
+}
+
+static inline void cpu_set_tls(CPUNios2State *env, target_ulong newtls)
+{
+    /* Linux kernel 3.10 does not pay any attention to CLONE_SETTLS
+     * in copy_thread(), so QEMU need not do so either.
+     */
+}
+
+#endif
diff --git a/linux-user/nios2/target_signal.h b/linux-user/nios2/target_signal.h
new file mode 100644
index 0000000..23a8267
--- /dev/null
+++ b/linux-user/nios2/target_signal.h
@@ -0,0 +1,26 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+    abi_long ss_sp;
+    abi_ulong ss_size;
+    abi_long ss_flags;
+} target_stack_t;
+
+/* sigaltstack controls  */
+#define TARGET_SS_ONSTACK     1
+#define TARGET_SS_DISABLE     2
+
+#define TARGET_MINSIGSTKSZ    2048
+#define TARGET_SIGSTKSZ       8192
+
+static inline abi_ulong get_sp_from_cpustate(CPUNios2State *state)
+{
+    return state->regs[R_SP];
+}
+
+#endif /* TARGET_SIGNAL_H */
diff --git a/linux-user/nios2/target_structs.h b/linux-user/nios2/target_structs.h
new file mode 100644
index 0000000..8713772
--- /dev/null
+++ b/linux-user/nios2/target_structs.h
@@ -0,0 +1,58 @@
+/*
+ * Nios2 specific structures for linux-user
+ *
+ * Copyright (c) 2016 Marek Vasut <marex@denx.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_ushort mode;                    /* Read/write permission.  */
+    abi_ushort __pad1;
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+#endif
diff --git a/linux-user/nios2/target_syscall.h b/linux-user/nios2/target_syscall.h
new file mode 100644
index 0000000..23da0d6
--- /dev/null
+++ b/linux-user/nios2/target_syscall.h
@@ -0,0 +1,37 @@
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
+
+#define UNAME_MACHINE "nios2"
+#define UNAME_MINIMUM_RELEASE "3.19.0"
+
+struct target_pt_regs {
+	unsigned long  r8;	/* r8-r15 Caller-saved GP registers */
+	unsigned long  r9;
+	unsigned long  r10;
+	unsigned long  r11;
+	unsigned long  r12;
+	unsigned long  r13;
+	unsigned long  r14;
+	unsigned long  r15;
+	unsigned long  r1;	/* Assembler temporary */
+	unsigned long  r2;	/* Retval LS 32bits */
+	unsigned long  r3;	/* Retval MS 32bits */
+	unsigned long  r4;	/* r4-r7 Register arguments */
+	unsigned long  r5;
+	unsigned long  r6;
+	unsigned long  r7;
+	unsigned long  orig_r2;	/* Copy of r2 ?? */
+	unsigned long  ra;	/* Return address */
+	unsigned long  fp;	/* Frame pointer */
+	unsigned long  sp;	/* Stack pointer */
+	unsigned long  gp;	/* Global pointer */
+	unsigned long  estatus;
+	unsigned long  ea;	/* Exception return address (pc) */
+	unsigned long  orig_r7;
+};
+
+#define TARGET_MINSIGSTKSZ 2048
+#define TARGET_MLOCKALL_MCL_CURRENT 1
+#define TARGET_MLOCKALL_MCL_FUTURE  2
+
+#endif  /* TARGET_SYSCALL_H */
diff --git a/linux-user/nios2/termbits.h b/linux-user/nios2/termbits.h
new file mode 100644
index 0000000..b64ba97
--- /dev/null
+++ b/linux-user/nios2/termbits.h
@@ -0,0 +1,220 @@
+/* from asm/termbits.h */
+/* NOTE: exactly the same as i386 */
+
+#define TARGET_NCCS 19
+
+struct target_termios {
+    unsigned int c_iflag;               /* input mode flags */
+    unsigned int c_oflag;               /* output mode flags */
+    unsigned int c_cflag;               /* control mode flags */
+    unsigned int c_lflag;               /* local mode flags */
+    unsigned char c_line;                    /* line discipline */
+    unsigned char c_cc[TARGET_NCCS];                /* control characters */
+};
+
+/* c_iflag bits */
+#define TARGET_IGNBRK  0000001
+#define TARGET_BRKINT  0000002
+#define TARGET_IGNPAR  0000004
+#define TARGET_PARMRK  0000010
+#define TARGET_INPCK   0000020
+#define TARGET_ISTRIP  0000040
+#define TARGET_INLCR   0000100
+#define TARGET_IGNCR   0000200
+#define TARGET_ICRNL   0000400
+#define TARGET_IUCLC   0001000
+#define TARGET_IXON    0002000
+#define TARGET_IXANY   0004000
+#define TARGET_IXOFF   0010000
+#define TARGET_IMAXBEL 0020000
+#define TARGET_IUTF8   0040000
+
+/* c_oflag bits */
+#define TARGET_OPOST   0000001
+#define TARGET_OLCUC   0000002
+#define TARGET_ONLCR   0000004
+#define TARGET_OCRNL   0000010
+#define TARGET_ONOCR   0000020
+#define TARGET_ONLRET  0000040
+#define TARGET_OFILL   0000100
+#define TARGET_OFDEL   0000200
+#define TARGET_NLDLY   0000400
+#define   TARGET_NL0   0000000
+#define   TARGET_NL1   0000400
+#define TARGET_CRDLY   0003000
+#define   TARGET_CR0   0000000
+#define   TARGET_CR1   0001000
+#define   TARGET_CR2   0002000
+#define   TARGET_CR3   0003000
+#define TARGET_TABDLY  0014000
+#define   TARGET_TAB0  0000000
+#define   TARGET_TAB1  0004000
+#define   TARGET_TAB2  0010000
+#define   TARGET_TAB3  0014000
+#define   TARGET_XTABS 0014000
+#define TARGET_BSDLY   0020000
+#define   TARGET_BS0   0000000
+#define   TARGET_BS1   0020000
+#define TARGET_VTDLY   0040000
+#define   TARGET_VT0   0000000
+#define   TARGET_VT1   0040000
+#define TARGET_FFDLY   0100000
+#define   TARGET_FF0   0000000
+#define   TARGET_FF1   0100000
+
+/* c_cflag bit meaning */
+#define TARGET_CBAUD   0010017
+#define  TARGET_B0     0000000         /* hang up */
+#define  TARGET_B50    0000001
+#define  TARGET_B75    0000002
+#define  TARGET_B110   0000003
+#define  TARGET_B134   0000004
+#define  TARGET_B150   0000005
+#define  TARGET_B200   0000006
+#define  TARGET_B300   0000007
+#define  TARGET_B600   0000010
+#define  TARGET_B1200  0000011
+#define  TARGET_B1800  0000012
+#define  TARGET_B2400  0000013
+#define  TARGET_B4800  0000014
+#define  TARGET_B9600  0000015
+#define  TARGET_B19200 0000016
+#define  TARGET_B38400 0000017
+#define TARGET_EXTA B19200
+#define TARGET_EXTB B38400
+#define TARGET_CSIZE   0000060
+#define   TARGET_CS5   0000000
+#define   TARGET_CS6   0000020
+#define   TARGET_CS7   0000040
+#define   TARGET_CS8   0000060
+#define TARGET_CSTOPB  0000100
+#define TARGET_CREAD   0000200
+#define TARGET_PARENB  0000400
+#define TARGET_PARODD  0001000
+#define TARGET_HUPCL   0002000
+#define TARGET_CLOCAL  0004000
+#define TARGET_CBAUDEX 0010000
+#define  TARGET_B57600  0010001
+#define  TARGET_B115200 0010002
+#define  TARGET_B230400 0010003
+#define  TARGET_B460800 0010004
+#define TARGET_CIBAUD    002003600000  /* input baud rate (not used) */
+#define TARGET_CMSPAR    010000000000  /* mark or space (stick) parity */
+#define TARGET_CRTSCTS   020000000000  /* flow control */
+
+/* c_lflag bits */
+#define TARGET_ISIG    0000001
+#define TARGET_ICANON  0000002
+#define TARGET_XCASE   0000004
+#define TARGET_ECHO    0000010
+#define TARGET_ECHOE   0000020
+#define TARGET_ECHOK   0000040
+#define TARGET_ECHONL  0000100
+#define TARGET_NOFLSH  0000200
+#define TARGET_TOSTOP  0000400
+#define TARGET_ECHOCTL 0001000
+#define TARGET_ECHOPRT 0002000
+#define TARGET_ECHOKE  0004000
+#define TARGET_FLUSHO  0010000
+#define TARGET_PENDIN  0040000
+#define TARGET_IEXTEN  0100000
+
+/* c_cc character offsets */
+#define TARGET_VINTR    0
+#define TARGET_VQUIT    1
+#define TARGET_VERASE   2
+#define TARGET_VKILL    3
+#define TARGET_VEOF     4
+#define TARGET_VTIME    5
+#define TARGET_VMIN     6
+#define TARGET_VSWTC    7
+#define TARGET_VSTART   8
+#define TARGET_VSTOP    9
+#define TARGET_VSUSP    10
+#define TARGET_VEOL     11
+#define TARGET_VREPRINT 12
+#define TARGET_VDISCARD 13
+#define TARGET_VWERASE  14
+#define TARGET_VLNEXT   15
+#define TARGET_VEOL2    16
+
+/* ioctls */
+
+#define TARGET_TCGETS           0x5401
+#define TARGET_TCSETS           0x5402
+#define TARGET_TCSETSW          0x5403
+#define TARGET_TCSETSF          0x5404
+#define TARGET_TCGETA           0x5405
+#define TARGET_TCSETA           0x5406
+#define TARGET_TCSETAW          0x5407
+#define TARGET_TCSETAF          0x5408
+#define TARGET_TCSBRK           0x5409
+#define TARGET_TCXONC           0x540A
+#define TARGET_TCFLSH           0x540B
+
+#define TARGET_TIOCEXCL         0x540C
+#define TARGET_TIOCNXCL         0x540D
+#define TARGET_TIOCSCTTY        0x540E
+#define TARGET_TIOCGPGRP        0x540F
+#define TARGET_TIOCSPGRP        0x5410
+#define TARGET_TIOCOUTQ         0x5411
+#define TARGET_TIOCSTI          0x5412
+#define TARGET_TIOCGWINSZ       0x5413
+#define TARGET_TIOCSWINSZ       0x5414
+#define TARGET_TIOCMGET         0x5415
+#define TARGET_TIOCMBIS         0x5416
+#define TARGET_TIOCMBIC         0x5417
+#define TARGET_TIOCMSET         0x5418
+#define TARGET_TIOCGSOFTCAR     0x5419
+#define TARGET_TIOCSSOFTCAR     0x541A
+#define TARGET_FIONREAD         0x541B
+#define TARGET_TIOCINQ          TARGET_FIONREAD
+#define TARGET_TIOCLINUX        0x541C
+#define TARGET_TIOCCONS         0x541D
+#define TARGET_TIOCGSERIAL      0x541E
+#define TARGET_TIOCSSERIAL      0x541F
+#define TARGET_TIOCPKT          0x5420
+#define TARGET_FIONBIO          0x5421
+#define TARGET_TIOCNOTTY        0x5422
+#define TARGET_TIOCSETD         0x5423
+#define TARGET_TIOCGETD         0x5424
+#define TARGET_TCSBRKP          0x5425 /* Needed for POSIX tcsendbreak() */
+#define TARGET_TIOCTTYGSTRUCT   0x5426 /* For debugging only */
+#define TARGET_TIOCSBRK         0x5427 /* BSD compatibility */
+#define TARGET_TIOCCBRK         0x5428 /* BSD compatibility */
+#define TARGET_TIOCGSID         0x5429 /* Return the session ID of FD */
+#define TARGET_TIOCGPTN         TARGET_IOR('T', 0x30, unsigned int)
+        /* Get Pty Number (of pty-mux device) */
+#define TARGET_TIOCSPTLCK       TARGET_IOW('T', 0x31, int)
+        /* Lock/unlock Pty */
+
+#define TARGET_FIONCLEX         0x5450  /* these numbers need to be adjusted. */
+#define TARGET_FIOCLEX          0x5451
+#define TARGET_FIOASYNC         0x5452
+#define TARGET_TIOCSERCONFIG    0x5453
+#define TARGET_TIOCSERGWILD     0x5454
+#define TARGET_TIOCSERSWILD     0x5455
+#define TARGET_TIOCGLCKTRMIOS   0x5456
+#define TARGET_TIOCSLCKTRMIOS   0x5457
+#define TARGET_TIOCSERGSTRUCT   0x5458 /* For debugging only */
+#define TARGET_TIOCSERGETLSR    0x5459 /* Get line status register */
+#define TARGET_TIOCSERGETMULTI  0x545A /* Get multiport config  */
+#define TARGET_TIOCSERSETMULTI  0x545B /* Set multiport config */
+
+#define TARGET_TIOCMIWAIT      0x545C
+        /* wait for a change on serial input line(s) */
+#define TARGET_TIOCGICOUNT     0x545D
+        /* read serial port inline interrupt counts */
+#define TARGET_TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
+#define TARGET_TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
+
+/* Used for packet mode */
+#define TARGET_TIOCPKT_DATA              0
+#define TARGET_TIOCPKT_FLUSHREAD         1
+#define TARGET_TIOCPKT_FLUSHWRITE        2
+#define TARGET_TIOCPKT_STOP              4
+#define TARGET_TIOCPKT_START             8
+#define TARGET_TIOCPKT_NOSTOP           16
+#define TARGET_TIOCPKT_DOSTOP           32
+
+#define TARGET_TIOCSER_TEMT    0x01 /* Transmitter physically empty */
diff --git a/linux-user/signal.c b/linux-user/signal.c
index c750053..b524b87 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -254,7 +254,7 @@ int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
 }
 
 #if !defined(TARGET_OPENRISC) && !defined(TARGET_UNICORE32) && \
-    !defined(TARGET_X86_64)
+    !defined(TARGET_X86_64) && !defined(TARGET_NIOS2)
 /* Just set the guest's signal mask to the specified value; the
  * caller is assumed to have called block_signals() already.
  */
@@ -3922,6 +3922,239 @@ long do_rt_sigreturn(CPUCRISState *env)
     return -TARGET_ENOSYS;
 }
 
+#elif defined(TARGET_NIOS2)
+
+#define MCONTEXT_VERSION 2
+
+struct target_sigcontext {
+    int version;
+    unsigned long gregs[32];
+};
+
+struct target_ucontext {
+    abi_ulong tuc_flags;
+    abi_ulong tuc_link;
+    target_stack_t tuc_stack;
+    struct target_sigcontext tuc_mcontext;
+    target_sigset_t tuc_sigmask;   /* mask last for extensibility */
+};
+
+struct target_rt_sigframe {
+    struct target_siginfo info;
+    struct target_ucontext uc;
+};
+
+static inline unsigned long sigsp(unsigned long sp, struct target_sigaction *ka)
+{
+    if (unlikely((ka->sa_flags & SA_ONSTACK)) && ! sas_ss_flags(sp))
+#ifdef CONFIG_STACK_GROWSUP
+        return target_sigaltstack_used.ss_sp;
+
+#else
+        return target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+#endif
+    return sp;
+}
+
+static int rt_setup_ucontext(struct target_ucontext *uc, CPUNios2State *env)
+{
+    unsigned long *gregs = uc->tuc_mcontext.gregs;
+
+    __put_user(MCONTEXT_VERSION, &uc->tuc_mcontext.version);
+    __put_user(env->regs[1], &gregs[0]);
+    __put_user(env->regs[2], &gregs[1]);
+    __put_user(env->regs[3], &gregs[2]);
+    __put_user(env->regs[4], &gregs[3]);
+    __put_user(env->regs[5], &gregs[4]);
+    __put_user(env->regs[6], &gregs[5]);
+    __put_user(env->regs[7], &gregs[6]);
+    __put_user(env->regs[8], &gregs[7]);
+    __put_user(env->regs[9], &gregs[8]);
+    __put_user(env->regs[10], &gregs[9]);
+    __put_user(env->regs[11], &gregs[10]);
+    __put_user(env->regs[12], &gregs[11]);
+    __put_user(env->regs[13], &gregs[12]);
+    __put_user(env->regs[14], &gregs[13]);
+    __put_user(env->regs[15], &gregs[14]);
+    __put_user(env->regs[16], &gregs[15]);
+    __put_user(env->regs[17], &gregs[16]);
+    __put_user(env->regs[18], &gregs[17]);
+    __put_user(env->regs[19], &gregs[18]);
+    __put_user(env->regs[20], &gregs[19]);
+    __put_user(env->regs[21], &gregs[20]);
+    __put_user(env->regs[22], &gregs[21]);
+    __put_user(env->regs[23], &gregs[22]);
+    __put_user(env->regs[R_RA], &gregs[23]);
+    __put_user(env->regs[R_FP], &gregs[24]);
+    __put_user(env->regs[R_GP], &gregs[25]);
+    __put_user(env->regs[R_EA], &gregs[27]);
+    __put_user(env->regs[R_SP], &gregs[28]);
+
+    return 0;
+}
+
+static int rt_restore_ucontext(CPUNios2State *env, struct target_ucontext *uc,
+                               int *pr2)
+{
+    int temp;
+    abi_ulong frame_addr = env->regs[R_SP];
+    unsigned long *gregs = uc->tuc_mcontext.gregs;
+    int err;
+
+    /* Always make any pending restarted system calls return -EINTR */
+    //current->restart_block.fn = do_no_restart_syscall;
+
+    __get_user(temp, &uc->tuc_mcontext.version);
+    if (temp != MCONTEXT_VERSION)
+        goto badframe;
+
+    /* restore passed registers */
+    __get_user(env->regs[1], &gregs[0]);
+    __get_user(env->regs[2], &gregs[1]);
+    __get_user(env->regs[3], &gregs[2]);
+    __get_user(env->regs[4], &gregs[3]);
+    __get_user(env->regs[5], &gregs[4]);
+    __get_user(env->regs[6], &gregs[5]);
+    __get_user(env->regs[7], &gregs[6]);
+    __get_user(env->regs[8], &gregs[7]);
+    __get_user(env->regs[9], &gregs[8]);
+    __get_user(env->regs[10], &gregs[9]);
+    __get_user(env->regs[11], &gregs[10]);
+    __get_user(env->regs[12], &gregs[11]);
+    __get_user(env->regs[13], &gregs[12]);
+    __get_user(env->regs[14], &gregs[13]);
+    __get_user(env->regs[15], &gregs[14]);
+    __get_user(env->regs[16], &gregs[15]);
+    __get_user(env->regs[17], &gregs[16]);
+    __get_user(env->regs[18], &gregs[17]);
+    __get_user(env->regs[19], &gregs[18]);
+    __get_user(env->regs[20], &gregs[19]);
+    __get_user(env->regs[21], &gregs[20]);
+    __get_user(env->regs[22], &gregs[21]);
+    __get_user(env->regs[23], &gregs[22]);
+    /* gregs[23] is handled below */
+    __get_user(env->regs[R_FP], &gregs[24]);  /* Verify, should this be
+                            settable */
+    __get_user(env->regs[R_GP], &gregs[25]);  /* Verify, should this be
+                            settable */
+
+    __get_user(temp, &gregs[26]);  /* Not really necessary no user
+                            settable bits */
+    __get_user(env->regs[R_EA], &gregs[27]);
+
+    __get_user(env->regs[R_RA], &gregs[23]);
+    __get_user(env->regs[R_SP], &gregs[28]);
+
+    if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe, uc.tuc_stack), 0,
+                       get_sp_from_cpustate(env)) == -EFAULT) {
+        goto badframe;
+    }
+
+    *pr2 = env->regs[2];
+    return err;
+
+badframe:
+    return 1;
+}
+
+static void *get_sigframe(struct target_sigaction *ka, CPUNios2State *env,
+			  size_t frame_size)
+{
+    unsigned long usp;
+
+    /* Default to using normal stack.  */
+    usp = env->regs[R_SP];
+
+    /* This is the X/Open sanctioned signal stack switching.  */
+    usp = sigsp(usp, ka);
+
+    /* Verify, is it 32 or 64 bit aligned */
+    return (void *)((usp - frame_size) & -8UL);
+}
+
+static void setup_rt_frame(int sig, struct target_sigaction *ka,
+                           target_siginfo_t *info,
+                           target_sigset_t *set,
+			   CPUNios2State *env)
+{
+    struct target_rt_sigframe *frame;
+    int i, err = 0;
+
+    frame = get_sigframe(ka, env, sizeof(*frame));
+
+    if (ka->sa_flags & SA_SIGINFO)
+            tswap_siginfo(&frame->info, info);
+
+    /* Create the ucontext.  */
+    __put_user(0, &frame->uc.tuc_flags);
+    __put_user(0, &frame->uc.tuc_link);
+    __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
+    __put_user(sas_ss_flags(env->regs[R_SP]), &frame->uc.tuc_stack.ss_flags);
+    __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
+    err |= rt_setup_ucontext(&frame->uc, env);
+    for (i = 0; i < TARGET_NSIG_WORDS; i++) {
+        __put_user((abi_ulong)set->sig[i],
+            (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
+    }
+
+    if (err)
+        goto give_sigsegv;
+
+    /* Set up to return from userspace; jump to fixed address sigreturn
+       trampoline on kuser page.  */
+    env->regs[R_RA] = (unsigned long) (0x1044);
+
+    /* Set up registers for signal handler */
+    env->regs[R_SP] = (unsigned long) frame;
+    env->regs[4] = (unsigned long) sig;
+    env->regs[5] = (unsigned long) &frame->info;
+    env->regs[6] = (unsigned long) &frame->uc;
+    env->regs[R_EA] = (unsigned long) ka->_sa_handler;
+    return;
+
+give_sigsegv:
+    if (sig == TARGET_SIGSEGV) {
+        ka->_sa_handler = TARGET_SIG_DFL;
+    }
+    force_sigsegv(sig);
+    return;
+}
+
+long do_sigreturn(CPUNios2State *env)
+{
+    trace_user_do_sigreturn(env, 0);
+    fprintf(stderr, "do_sigreturn: not implemented\n");
+    return -TARGET_ENOSYS;
+}
+
+long do_rt_sigreturn(CPUNios2State *env)
+{
+    /* Verify, can we follow the stack back */
+    abi_ulong frame_addr = env->regs[R_SP];
+    struct target_rt_sigframe *frame;
+    sigset_t set;
+    int rval;
+
+    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
+        goto badframe;
+    }
+
+    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
+    do_sigprocmask(SIG_SETMASK, &set, NULL);
+
+    if (rt_restore_ucontext(env, &frame->uc, &rval))
+        goto badframe;
+
+    unlock_user_struct(frame, frame_addr, 0);
+    return rval;
+
+badframe:
+    unlock_user_struct(frame, frame_addr, 0);
+    force_sig(TARGET_SIGSEGV);
+    return 0;
+}
+/* TARGET_NIOS2 */
+
 #elif defined(TARGET_OPENRISC)
 
 struct target_sigcontext {
@@ -5989,7 +6222,7 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
         /* prepare the stack frame of the virtual CPU */
 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) \
         || defined(TARGET_OPENRISC) || defined(TARGET_TILEGX) \
-        || defined(TARGET_PPC64)
+        || defined(TARGET_PPC64) || defined(TARGET_NIOS2)
         /* These targets do not have traditional signals.  */
         setup_rt_frame(sig, sa, &k->info, &target_old_set, cpu_env);
 #else
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 9fdbe86..36b0c1e 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -68,7 +68,8 @@
 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \
     || defined(TARGET_M68K) || defined(TARGET_CRIS) \
     || defined(TARGET_UNICORE32) || defined(TARGET_S390X) \
-    || defined(TARGET_OPENRISC) || defined(TARGET_TILEGX)
+    || defined(TARGET_OPENRISC) || defined(TARGET_TILEGX) \
+    || defined(TARGET_NIOS2)
 
 #define TARGET_IOC_SIZEBITS	14
 #define TARGET_IOC_DIRBITS	2
@@ -387,7 +388,7 @@ int do_sigaction(int sig, const struct target_sigaction *act,
     || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) \
     || defined(TARGET_MICROBLAZE) || defined(TARGET_UNICORE32) \
     || defined(TARGET_S390X) || defined(TARGET_OPENRISC) \
-    || defined(TARGET_TILEGX)
+    || defined(TARGET_TILEGX) || defined(TARGET_NIOS2)
 
 #if defined(TARGET_SPARC)
 #define TARGET_SA_NOCLDSTOP    8u
@@ -1944,7 +1945,7 @@ struct target_stat {
     abi_ulong  target_st_ctime_nsec;
     unsigned int __unused[2];
 };
-#elif defined(TARGET_OPENRISC) || defined(TARGET_TILEGX)
+#elif defined(TARGET_OPENRISC) || defined(TARGET_TILEGX) || defined(TARGET_NIOS2)
 
 /* These are the asm-generic versions of the stat and stat64 structures */
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 4/7] nios2: Add IIC interrupt controller emulation
  2016-09-27 23:30 [Qemu-devel] [PATCH V2 1/7] nios2: Add disas entries Marek Vasut
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support Marek Vasut
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 3/7] nios2: Add usermode binaries emulation Marek Vasut
@ 2016-09-27 23:30 ` Marek Vasut
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 5/7] nios2: Add periodic timer emulation Marek Vasut
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2016-09-27 23:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Chris Wulff, Marek Vasut, Jeff Da Silva, Ley Foon Tan,
	Sandra Loosemore, Yves Vandervennet

From: Chris Wulff <crwulff@gmail.com>

Add the Altera Nios2 internal interrupt controller model.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Chris Wulff <crwulff@gmail.com>
Cc: Jeff Da Silva <jdasilva@altera.com>
Cc: Ley Foon Tan <lftan@altera.com>
Cc: Sandra Loosemore <sandra@codesourcery.com>
Cc: Yves Vandervennet <yvanderv@altera.com>
---
 hw/intc/Makefile.objs |   1 +
 hw/intc/nios2_iic.c   | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 104 insertions(+)
 create mode 100644 hw/intc/nios2_iic.c

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 05ec21b..3c29fe7 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -38,3 +38,4 @@ obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_vic.o
 obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o
 obj-$(CONFIG_MIPS_CPS) += mips_gic.o
+obj-$(CONFIG_NIOS2) += nios2_iic.o
diff --git a/hw/intc/nios2_iic.c b/hw/intc/nios2_iic.c
new file mode 100644
index 0000000..6da2cce
--- /dev/null
+++ b/hw/intc/nios2_iic.c
@@ -0,0 +1,103 @@
+/*
+ * QEMU Altera Internal Interrupt Controller.
+ *
+ * Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+
+#include "hw/sysbus.h"
+#include "cpu.h"
+
+#define TYPE_ALTERA_IIC "altera,iic"
+#define ALTERA_IIC(obj) \
+    OBJECT_CHECK(AlteraIIC, (obj), TYPE_ALTERA_IIC)
+
+typedef struct AlteraIIC {
+    SysBusDevice  parent_obj;
+    void         *cpu;
+    qemu_irq      parent_irq;
+} AlteraIIC;
+
+static void update_irq(AlteraIIC *pv)
+{
+    CPUNios2State *env = &((Nios2CPU*)(pv->cpu))->env;
+
+    qemu_set_irq(pv->parent_irq,
+                 env->regs[CR_IPENDING] & env->regs[CR_IENABLE]);
+}
+
+static void irq_handler(void *opaque, int irq, int level)
+{
+    AlteraIIC *pv = opaque;
+    CPUNios2State *env = &((Nios2CPU*)(pv->cpu))->env;
+
+    env->regs[CR_IPENDING] &= ~(1 << irq);
+    env->regs[CR_IPENDING] |= !!level << irq;
+
+    update_irq(pv);
+}
+
+static void altera_iic_init(Object *obj)
+{
+    AlteraIIC *pv = ALTERA_IIC(obj);
+
+    qdev_init_gpio_in(DEVICE(pv), irq_handler, 32);
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &pv->parent_irq);
+}
+
+static Property altera_iic_properties[] = {
+    DEFINE_PROP_PTR("cpu", AlteraIIC, cpu),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void altera_iic_realize(DeviceState *dev, Error **errp)
+{
+    struct AlteraIIC *pv = ALTERA_IIC(dev);
+
+    if (!pv->cpu) {
+        error_setg(errp, "altera,iic: CPU not connected");
+        return;
+    }
+}
+
+static void altera_iic_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->props = altera_iic_properties;
+    /* Reason: pointer property "cpu" */
+    dc->cannot_instantiate_with_device_add_yet = true;
+    dc->realize = altera_iic_realize;
+}
+
+static TypeInfo altera_iic_info = {
+    .name          = "altera,iic",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(AlteraIIC),
+    .instance_init = altera_iic_init,
+    .class_init    = altera_iic_class_init,
+};
+
+static void altera_iic_register(void)
+{
+    type_register_static(&altera_iic_info);
+}
+
+type_init(altera_iic_register)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 5/7] nios2: Add periodic timer emulation
  2016-09-27 23:30 [Qemu-devel] [PATCH V2 1/7] nios2: Add disas entries Marek Vasut
                   ` (2 preceding siblings ...)
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 4/7] nios2: Add IIC interrupt controller emulation Marek Vasut
@ 2016-09-27 23:30 ` Marek Vasut
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 6/7] nios2: Add Altera 10M50 GHRD emulation Marek Vasut
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2016-09-27 23:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Chris Wulff, Marek Vasut, Jeff Da Silva, Ley Foon Tan,
	Sandra Loosemore, Yves Vandervennet

From: Chris Wulff <crwulff@gmail.com>

Add the Altera timer model.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Chris Wulff <crwulff@gmail.com>
Cc: Jeff Da Silva <jdasilva@altera.com>
Cc: Ley Foon Tan <lftan@altera.com>
Cc: Sandra Loosemore <sandra@codesourcery.com>
Cc: Yves Vandervennet <yvanderv@altera.com>
---
 hw/timer/Makefile.objs  |   1 +
 hw/timer/altera_timer.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 237 insertions(+)
 create mode 100644 hw/timer/altera_timer.c

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 7ba8c23..0867a64 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -18,6 +18,7 @@ common-obj-$(CONFIG_IMX) += imx_gpt.o
 common-obj-$(CONFIG_LM32) += lm32_timer.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
 
+obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_pwm.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
diff --git a/hw/timer/altera_timer.c b/hw/timer/altera_timer.c
new file mode 100644
index 0000000..4461438
--- /dev/null
+++ b/hw/timer/altera_timer.c
@@ -0,0 +1,236 @@
+/*
+ * QEMU model of the Altera timer.
+ *
+ * Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+
+#include "hw/sysbus.h"
+#include "sysemu/sysemu.h"
+#include "hw/ptimer.h"
+
+#define R_STATUS      0
+#define R_CONTROL     1
+#define R_PERIODL     2
+#define R_PERIODH     3
+#define R_SNAPL       4
+#define R_SNAPH       5
+#define R_MAX         6
+
+#define STATUS_TO     0x0001
+#define STATUS_RUN    0x0002
+
+#define CONTROL_ITO   0x0001
+#define CONTROL_CONT  0x0002
+#define CONTROL_START 0x0004
+#define CONTROL_STOP  0x0008
+
+#define TYPE_ALTERA_TIMER "ALTR.timer"
+#define ALTERA_TIMER(obj) \
+    OBJECT_CHECK(AlteraTimer, (obj), TYPE_ALTERA_TIMER)
+
+typedef struct AlteraTimer {
+    SysBusDevice  busdev;
+    MemoryRegion  mmio;
+    qemu_irq      irq;
+    uint32_t      freq_hz;
+    QEMUBH       *bh;
+    ptimer_state *ptimer;
+    uint32_t      regs[R_MAX];
+} AlteraTimer;
+
+static inline int timer_irq_state(AlteraTimer *t)
+{
+    return (t->regs[R_STATUS] & STATUS_TO) &&
+           (t->regs[R_CONTROL] & CONTROL_ITO);
+}
+
+static uint64_t timer_read(void *opaque, hwaddr addr,
+                           unsigned int size)
+{
+    AlteraTimer *t = opaque;
+    uint64_t r = 0;
+
+    addr >>= 2;
+    addr &= 0x7;
+    switch (addr) {
+    case R_CONTROL:
+        r = t->regs[R_CONTROL] & (CONTROL_ITO | CONTROL_CONT);
+        break;
+
+    default:
+        if (addr < ARRAY_SIZE(t->regs)) {
+            r = t->regs[addr];
+        }
+        break;
+    }
+
+    return r;
+}
+
+static void timer_write(void *opaque, hwaddr addr,
+                        uint64_t value, unsigned int size)
+{
+    AlteraTimer *t = opaque;
+    uint64_t tvalue;
+    uint32_t count = 0;
+    int irqState = timer_irq_state(t);
+
+    addr >>= 2;
+    addr &= 0x7;
+    switch (addr) {
+    case R_STATUS:
+        /* The timeout bit is cleared by writing the status register. */
+        t->regs[R_STATUS] &= ~STATUS_TO;
+        break;
+
+    case R_CONTROL:
+        t->regs[R_CONTROL] = value & (CONTROL_ITO | CONTROL_CONT);
+        if ((value & CONTROL_START) &&
+            !(t->regs[R_STATUS] & STATUS_RUN)) {
+            ptimer_run(t->ptimer, 1);
+            t->regs[R_STATUS] |= STATUS_RUN;
+        }
+        if ((value & CONTROL_STOP) && (t->regs[R_STATUS] & STATUS_RUN)) {
+            ptimer_stop(t->ptimer);
+            t->regs[R_STATUS] &= ~STATUS_RUN;
+        }
+        break;
+
+    case R_PERIODL:
+    case R_PERIODH:
+        t->regs[addr] = value & 0xFFFF;
+        if (t->regs[R_STATUS] & STATUS_RUN) {
+            ptimer_stop(t->ptimer);
+            t->regs[R_STATUS] &= ~STATUS_RUN;
+        }
+        tvalue = (t->regs[R_PERIODH] << 16) | t->regs[R_PERIODL];
+        ptimer_set_limit(t->ptimer, tvalue + 1, 1);
+        break;
+
+    case R_SNAPL:
+    case R_SNAPH:
+        count = ptimer_get_count(t->ptimer);
+        t->regs[R_SNAPL] = count & 0xFFFF;
+        t->regs[R_SNAPH] = count >> 16;
+        break;
+
+    default:
+        break;
+    }
+
+    if (irqState != timer_irq_state(t)) {
+        qemu_set_irq(t->irq, timer_irq_state(t));
+    }
+}
+
+static const MemoryRegionOps timer_ops = {
+    .read = timer_read,
+    .write = timer_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 4
+    }
+};
+
+static void timer_hit(void *opaque)
+{
+    AlteraTimer *t = opaque;
+    const uint64_t tvalue = (t->regs[R_PERIODH] << 16) | t->regs[R_PERIODL];
+
+    t->regs[R_STATUS] |= STATUS_TO;
+
+    ptimer_set_limit(t->ptimer, tvalue + 1, 1);
+
+    if (!(t->regs[R_CONTROL] & CONTROL_CONT)) {
+        t->regs[R_STATUS] &= ~STATUS_RUN;
+        ptimer_set_count(t->ptimer, tvalue);
+    } else {
+        ptimer_run(t->ptimer, 1);
+    }
+
+    qemu_set_irq(t->irq, timer_irq_state(t));
+}
+
+static void altera_timer_realize(DeviceState *dev, Error **errp)
+{
+    AlteraTimer *t = ALTERA_TIMER(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+    if (t->freq_hz == 0) {
+        error_setg(errp, "\"clock-frequency\" property must be provided.");
+	return;
+    }
+
+    t->bh = qemu_bh_new(timer_hit, t);
+    t->ptimer = ptimer_init(t->bh, PTIMER_POLICY_DEFAULT);
+    ptimer_set_freq(t->ptimer, t->freq_hz);
+
+    memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t,
+                          TYPE_ALTERA_TIMER, R_MAX * sizeof(uint32_t));
+    sysbus_init_mmio(sbd, &t->mmio);
+}
+
+static void altera_timer_init(Object *obj)
+{
+    AlteraTimer *t = ALTERA_TIMER(obj);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+    sysbus_init_irq(sbd, &t->irq);
+}
+
+static void altera_timer_reset(DeviceState *dev)
+{
+    AlteraTimer *t = ALTERA_TIMER(dev);
+
+    ptimer_stop(t->ptimer);
+    ptimer_set_limit(t->ptimer, 0xffffffff, 1);
+    memset(t->regs, 0, ARRAY_SIZE(t->regs));
+}
+
+static Property altera_timer_properties[] = {
+    DEFINE_PROP_UINT32("clock-frequency", AlteraTimer, freq_hz, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void altera_timer_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = altera_timer_realize;
+    dc->props = altera_timer_properties;
+    dc->reset = altera_timer_reset;
+}
+
+static const TypeInfo altera_timer_info = {
+    .name          = TYPE_ALTERA_TIMER,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(AlteraTimer),
+    .instance_init = altera_timer_init,
+    .class_init    = altera_timer_class_init,
+};
+
+static void altera_timer_register(void)
+{
+    type_register_static(&altera_timer_info);
+}
+
+type_init(altera_timer_register)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 6/7] nios2: Add Altera 10M50 GHRD emulation
  2016-09-27 23:30 [Qemu-devel] [PATCH V2 1/7] nios2: Add disas entries Marek Vasut
                   ` (3 preceding siblings ...)
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 5/7] nios2: Add periodic timer emulation Marek Vasut
@ 2016-09-27 23:30 ` Marek Vasut
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 7/7] nios2: Add support for Nios-II R1 Marek Vasut
  2016-10-15 13:15 ` [Qemu-devel] [V2,1/7] nios2: Add disas entries Romain Naour
  6 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2016-09-27 23:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marek Vasut, Chris Wulff, Jeff Da Silva, Ley Foon Tan,
	Sandra Loosemore, Yves Vandervennet

Add the Altera 10M50 Nios2 GHRD model. This allows emulating the
10M50 development kit with the Nios2 GHRD loaded in the FPGA. It
is possible to boot Linux kernel and run userspace, thus far only
from initrd as storage support is not yet implemented.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Chris Wulff <crwulff@gmail.com>
Cc: Jeff Da Silva <jdasilva@altera.com>
Cc: Ley Foon Tan <lftan@altera.com>
Cc: Sandra Loosemore <sandra@codesourcery.com>
Cc: Yves Vandervennet <yvanderv@altera.com>
---
 hw/nios2/10m50_devboard.c | 125 ++++++++++++++++++++++++++
 hw/nios2/Makefile.objs    |   1 +
 hw/nios2/boot.c           | 223 ++++++++++++++++++++++++++++++++++++++++++++++
 hw/nios2/boot.h           |  11 +++
 4 files changed, 360 insertions(+)
 create mode 100644 hw/nios2/10m50_devboard.c
 create mode 100644 hw/nios2/Makefile.objs
 create mode 100644 hw/nios2/boot.c
 create mode 100644 hw/nios2/boot.h

diff --git a/hw/nios2/10m50_devboard.c b/hw/nios2/10m50_devboard.c
new file mode 100644
index 0000000..8312fd9
--- /dev/null
+++ b/hw/nios2/10m50_devboard.c
@@ -0,0 +1,125 @@
+/*
+ * Altera 10M50 Nios2 GHRD
+ *
+ * Copyright (c) 2016 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on LabX device code
+ *
+ * Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+
+#include "hw/sysbus.h"
+#include "hw/hw.h"
+#include "hw/char/serial.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
+#include "qemu/config-file.h"
+
+#include "boot.h"
+
+#define BINARY_DEVICE_TREE_FILE		"10m50-devboard.dtb"
+
+static void nios2_10m50_ghrd_init(MachineState *machine)
+{
+    Nios2CPU *cpu;
+    DeviceState *dev;
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *phys_tcm = g_new(MemoryRegion, 1);
+    MemoryRegion *phys_tcm_alias = g_new(MemoryRegion, 1);
+    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
+    MemoryRegion *phys_ram_alias = g_new(MemoryRegion, 1);
+    ram_addr_t tcm_base = 0x0;
+    ram_addr_t tcm_size = 0x1000;    /* 1 kiB, but QEMU limit is 4 kiB */
+    ram_addr_t ram_base = 0x08000000;
+    ram_addr_t ram_size = 0x08000000;
+    qemu_irq *cpu_irq, irq[32];
+    int i;
+
+    /* Physical TCM (tb_ram_1k) with alias at 0xc0000000 */
+    memory_region_init_ram(phys_tcm, NULL, "nios2.tcm", tcm_size, &error_abort);
+    memory_region_init_alias(phys_tcm_alias, NULL, "nios2.tcm.alias",
+                             phys_tcm, 0, tcm_size);
+    vmstate_register_ram_global(phys_tcm);
+    memory_region_add_subregion(address_space_mem, tcm_base, phys_tcm);
+    memory_region_add_subregion(address_space_mem, 0xc0000000 + tcm_base,
+                                phys_tcm_alias);
+
+    /* Physical DRAM with alias at 0xc0000000 */
+    memory_region_init_ram(phys_ram, NULL, "nios2.ram", ram_size, &error_abort);
+    memory_region_init_alias(phys_ram_alias, NULL, "nios2.ram.alias",
+                             phys_ram, 0, ram_size);
+    vmstate_register_ram_global(phys_ram);
+    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
+    memory_region_add_subregion(address_space_mem, 0xc0000000 + ram_base,
+                                phys_ram_alias);
+
+    /* Create CPU -- FIXME */
+    cpu = cpu_nios2_init("nios2");
+
+    /* Register: CPU interrupt controller (PIC) */
+    cpu_irq = nios2_cpu_pic_init(cpu);
+
+    /* Register: Internal Interrupt Controller (IIC) */
+    dev = qdev_create(NULL, "altera,iic");
+    qdev_prop_set_ptr(dev, "cpu", cpu);
+    qdev_init_nofail(dev);
+    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irq[0]);
+    for (i = 0; i < 32; i++)
+        irq[i] = qdev_get_gpio_in(dev, i);
+
+    /* Register: Altera 16550 UART */
+    serial_mm_init(address_space_mem, 0xf8001600, 2, irq[1], 115200,
+                   serial_hds[0], DEVICE_NATIVE_ENDIAN);
+
+    /* Register: Timer sys_clk_timer  */
+    dev = qdev_create(NULL, "ALTR.timer");
+    qdev_prop_set_uint32(dev, "clock-frequency", 75 * 1000000);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xf8001440);
+    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[0]);
+
+    /* Register: Timer sys_clk_timer_1  */
+    dev = qdev_create(NULL, "ALTR.timer");
+    qdev_prop_set_uint32(dev, "clock-frequency", 75 * 1000000);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xe0000880);
+    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[5]);
+
+    /* Configure new exception vectors and reset CPU for it to take effect. */
+    cpu->env.reset_addr = 0xd4000000;
+    cpu->env.exception_addr = 0xc8000120;
+    cpu->env.fast_tlb_miss_addr = 0xc0000100;
+
+    nios2_load_kernel(cpu, ram_base, ram_size, machine->initrd_filename,
+                      BINARY_DEVICE_TREE_FILE, NULL);
+}
+
+static void nios2_10m50_ghrd_machine_init(struct MachineClass *mc)
+{
+    mc->desc = "Altera 10M50 GHRD Nios II design";
+    mc->init = nios2_10m50_ghrd_init;
+    mc->is_default = 1;
+}
+
+DEFINE_MACHINE("10m50-ghrd", nios2_10m50_ghrd_machine_init);
diff --git a/hw/nios2/Makefile.objs b/hw/nios2/Makefile.objs
new file mode 100644
index 0000000..6b5c421
--- /dev/null
+++ b/hw/nios2/Makefile.objs
@@ -0,0 +1 @@
+obj-y = boot.o cpu_pic.o 10m50_devboard.o
diff --git a/hw/nios2/boot.c b/hw/nios2/boot.c
new file mode 100644
index 0000000..bd26565
--- /dev/null
+++ b/hw/nios2/boot.c
@@ -0,0 +1,223 @@
+/*
+ * Nios2 kernel loader
+ *
+ * Copyright (c) 2016 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on microblaze kernel loader
+ *
+ * Copyright (c) 2012 Peter Crosthwaite <peter.crosthwaite@petalogix.com>
+ * Copyright (c) 2012 PetaLogix
+ * Copyright (c) 2009 Edgar E. Iglesias.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
+#include "qemu/error-report.h"
+#include "qemu-common.h"
+#include "sysemu/device_tree.h"
+#include "sysemu/sysemu.h"
+#include "hw/loader.h"
+#include "elf.h"
+#include "qemu/cutils.h"
+
+#include "boot.h"
+
+#define NIOS2_MAGIC    0x534f494e
+
+static struct nios2_boot_info {
+    void (*machine_cpu_reset)(Nios2CPU *);
+    uint32_t bootstrap_pc;
+    uint32_t cmdline;
+    uint32_t initrd_start;
+    uint32_t initrd_end;
+    uint32_t fdt;
+} boot_info;
+
+static void main_cpu_reset(void *opaque)
+{
+    Nios2CPU *cpu = opaque;
+    CPUState *cs = CPU(cpu);
+    CPUNios2State *env = &cpu->env;
+
+    cpu_reset(CPU(cpu));
+
+    env->regs[R_ARG0] = NIOS2_MAGIC;
+    env->regs[R_ARG1] = boot_info.initrd_start;
+    env->regs[R_ARG2] = boot_info.fdt;
+    env->regs[R_ARG3] = boot_info.cmdline;
+
+    cpu_set_pc(cs, boot_info.bootstrap_pc);
+    if (boot_info.machine_cpu_reset) {
+        boot_info.machine_cpu_reset(cpu);
+    }
+}
+
+static int nios2_load_dtb(struct nios2_boot_info bi, const uint32_t ramsize,
+                          const char *kernel_cmdline, const char *dtb_filename)
+{
+    int fdt_size;
+    void *fdt = NULL;
+    int r;
+
+    if (dtb_filename) {
+        fdt = load_device_tree(dtb_filename, &fdt_size);
+    }
+    if (!fdt) {
+        return 0;
+    }
+
+    if (kernel_cmdline) {
+        r = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
+                                    kernel_cmdline);
+        if (r < 0) {
+            fprintf(stderr, "couldn't set /chosen/bootargs\n");
+        }
+    }
+
+    if (bi.initrd_start) {
+        qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
+                              bi.initrd_start);
+
+        qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
+                              bi.initrd_end);
+    }
+
+    cpu_physical_memory_write(bi.fdt, fdt, fdt_size);
+    return fdt_size;
+}
+
+static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
+{
+    return addr - 0xc0000000LL;
+}
+
+void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
+                            uint32_t ramsize,
+                            const char *initrd_filename,
+                            const char *dtb_filename,
+                            void (*machine_cpu_reset)(Nios2CPU *))
+{
+    QemuOpts *machine_opts;
+    const char *kernel_filename;
+    const char *kernel_cmdline;
+    const char *dtb_arg;
+    char *filename = NULL;
+
+    machine_opts = qemu_get_machine_opts();
+    kernel_filename = qemu_opt_get(machine_opts, "kernel");
+    kernel_cmdline = qemu_opt_get(machine_opts, "append");
+    dtb_arg = qemu_opt_get(machine_opts, "dtb");
+    /* default to pcbios dtb as passed by machine_init */
+    if (!dtb_arg) {
+        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename);
+    }
+
+    boot_info.machine_cpu_reset = machine_cpu_reset;
+    qemu_register_reset(main_cpu_reset, cpu);
+
+    if (kernel_filename) {
+        int kernel_size, fdt_size;
+        uint64_t entry, low, high;
+        uint32_t base32;
+        int big_endian = 0;
+
+#ifdef TARGET_WORDS_BIGENDIAN
+        big_endian = 1;
+#endif
+
+        /* Boots a kernel elf binary. */
+        kernel_size = load_elf(kernel_filename, NULL, NULL,
+                               &entry, &low, &high,
+                               big_endian, EM_ALTERA_NIOS2, 0, 0);
+        base32 = entry;
+        if (base32 == 0xc0000000) {
+            kernel_size = load_elf(kernel_filename, translate_kernel_address,
+                                   NULL, &entry, NULL, NULL,
+                                   big_endian, EM_ALTERA_NIOS2, 0, 0);
+        }
+
+        /* Always boot into physical ram. */
+        boot_info.bootstrap_pc = ddr_base + 0xc0000000 + (entry & 0x07ffffff);
+
+        /* If it wasn't an ELF image, try an u-boot image. */
+        if (kernel_size < 0) {
+            hwaddr uentry, loadaddr;
+
+            kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0,
+                                      NULL, NULL);
+            boot_info.bootstrap_pc = uentry;
+            high = loadaddr + kernel_size;
+        }
+
+        /* Not an ELF image nor an u-boot image, try a RAW image. */
+        if (kernel_size < 0) {
+            kernel_size = load_image_targphys(kernel_filename, ddr_base,
+                                              ram_size);
+            boot_info.bootstrap_pc = ddr_base;
+            high = ddr_base + kernel_size;
+        }
+
+        high = ROUND_UP(high, 1024 * 1024);
+
+        /* If initrd is available, it goes after the kernel, aligned to 1M. */
+        if (initrd_filename) {
+            int initrd_size;
+            uint32_t initrd_offset;
+
+            boot_info.initrd_start = high;
+            initrd_offset = boot_info.initrd_start - ddr_base;
+
+            initrd_size = load_ramdisk(initrd_filename,
+                                       boot_info.initrd_start,
+                                       ram_size - initrd_offset);
+            if (initrd_size < 0) {
+                initrd_size = load_image_targphys(initrd_filename,
+                                                  boot_info.initrd_start,
+                                                  ram_size - initrd_offset);
+            }
+            if (initrd_size < 0) {
+                error_report("qemu: could not load initrd '%s'",
+                             initrd_filename);
+                exit(EXIT_FAILURE);
+            }
+            high += initrd_size;
+        }
+	high = ROUND_UP(high, 4);
+        boot_info.initrd_end = high;
+
+        /* Device tree must be placed right after initrd (if available) */
+        boot_info.fdt = high;
+        fdt_size = nios2_load_dtb(boot_info, ram_size, kernel_cmdline,
+                                  /* Preference a -dtb argument */
+                                  dtb_arg ? dtb_arg : filename);
+        high += fdt_size;
+
+        /* Kernel command is at the end, 4k aligned. */
+        boot_info.cmdline = ROUND_UP(high, 4096);
+        if (kernel_cmdline && strlen(kernel_cmdline)) {
+            pstrcpy_targphys("cmdline", boot_info.cmdline, 256, kernel_cmdline);
+        }
+    }
+    g_free(filename);
+}
diff --git a/hw/nios2/boot.h b/hw/nios2/boot.h
new file mode 100644
index 0000000..edf3046
--- /dev/null
+++ b/hw/nios2/boot.h
@@ -0,0 +1,11 @@
+#ifndef __NIOS2_BOOT__
+#define __NIOS2_BOOT__
+
+#include "hw/hw.h"
+#include "cpu.h"
+
+void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base, uint32_t ramsize,
+                       const char *initrd_filename, const char *dtb_filename,
+                       void (*machine_cpu_reset)(Nios2CPU *));
+
+#endif /* __NIOS2_BOOT__ */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 7/7] nios2: Add support for Nios-II R1
  2016-09-27 23:30 [Qemu-devel] [PATCH V2 1/7] nios2: Add disas entries Marek Vasut
                   ` (4 preceding siblings ...)
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 6/7] nios2: Add Altera 10M50 GHRD emulation Marek Vasut
@ 2016-09-27 23:30 ` Marek Vasut
  2016-10-15 13:15 ` [Qemu-devel] [V2,1/7] nios2: Add disas entries Romain Naour
  6 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2016-09-27 23:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marek Vasut, Chris Wulff, Jeff Da Silva, Ley Foon Tan,
	Sandra Loosemore, Yves Vandervennet

Add remaining bits of the Altera NiosII R1 support into qemu, which
is documentation, MAINTAINERS file entry, configure bits, arch_init
and configuration files for both linux-user (userland binaries) and
softmmu (hardware emulation).

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Chris Wulff <crwulff@gmail.com>
Cc: Jeff Da Silva <jdasilva@altera.com>
Cc: Ley Foon Tan <lftan@altera.com>
Cc: Sandra Loosemore <sandra@codesourcery.com>
Cc: Yves Vandervennet <yvanderv@altera.com>
---
 MAINTAINERS                          | 8 ++++++++
 arch_init.c                          | 2 ++
 configure                            | 5 +++++
 default-configs/nios2-linux-user.mak | 1 +
 default-configs/nios2-softmmu.mak    | 6 ++++++
 include/sysemu/arch_init.h           | 1 +
 qemu-doc.texi                        | 3 +++
 7 files changed, 26 insertions(+)
 create mode 100644 default-configs/nios2-linux-user.mak
 create mode 100644 default-configs/nios2-softmmu.mak

diff --git a/MAINTAINERS b/MAINTAINERS
index f3c1f7f..ad366ca 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -158,6 +158,14 @@ S: Maintained
 F: target-moxie/
 F: disas/moxie.c
 
+NiosII
+M: Chris Wulff <crwulff@gmail.com>
+M: Marek Vasut <marex@denx.de>
+S: Maintained
+F: target-nios2/
+F: hw/nios2/
+F: disas/nios2.c
+
 OpenRISC
 M: Jia Liu <proljc@gmail.com>
 S: Maintained
diff --git a/arch_init.c b/arch_init.c
index 5cc58b2..20d83ff 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -64,6 +64,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_MIPS
 #elif defined(TARGET_MOXIE)
 #define QEMU_ARCH QEMU_ARCH_MOXIE
+#elif defined(TARGET_NIOS2)
+#define QEMU_ARCH QEMU_ARCH_NIOS2
 #elif defined(TARGET_OPENRISC)
 #define QEMU_ARCH QEMU_ARCH_OPENRISC
 #elif defined(TARGET_PPC)
diff --git a/configure b/configure
index 8fa62ad..21d1e34 100755
--- a/configure
+++ b/configure
@@ -5669,6 +5669,8 @@ case "$target_name" in
   ;;
   moxie)
   ;;
+  nios2)
+  ;;
   or32)
     TARGET_ARCH=openrisc
     TARGET_BASE_ARCH=openrisc
@@ -5862,6 +5864,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   moxie*)
     disas_config "MOXIE"
   ;;
+  nios2)
+    disas_config "NIOS2"
+  ;;
   or32)
     disas_config "OPENRISC"
   ;;
diff --git a/default-configs/nios2-linux-user.mak b/default-configs/nios2-linux-user.mak
new file mode 100644
index 0000000..5be3eb7
--- /dev/null
+++ b/default-configs/nios2-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for nios2-linux-user
diff --git a/default-configs/nios2-softmmu.mak b/default-configs/nios2-softmmu.mak
new file mode 100644
index 0000000..74dc70c
--- /dev/null
+++ b/default-configs/nios2-softmmu.mak
@@ -0,0 +1,6 @@
+# Default configuration for nios2-softmmu
+
+CONFIG_NIOS2=y
+CONFIG_SERIAL=y
+CONFIG_PTIMER=y
+CONFIG_ALTERA_TIMER=y
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 1c9dad1..fe60e11 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -23,6 +23,7 @@ enum {
     QEMU_ARCH_UNICORE32 = (1 << 14),
     QEMU_ARCH_MOXIE = (1 << 15),
     QEMU_ARCH_TRICORE = (1 << 16),
+    QEMU_ARCH_NIOS2 = (1 << 17),
 };
 
 extern const uint32_t arch_type;
diff --git a/qemu-doc.texi b/qemu-doc.texi
index f37fd31..1e40d09 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2856,6 +2856,9 @@ The binary format is detected automatically.
 @command{qemu-mips} TODO.
 @command{qemu-mipsel} TODO.
 
+@cindex user mode (NiosII)
+@command{qemu-nios2} TODO.
+
 @cindex user mode (PowerPC)
 @command{qemu-ppc64abi32} TODO.
 @command{qemu-ppc64} TODO.
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support Marek Vasut
@ 2016-09-29  1:05   ` Richard Henderson
  2016-10-18  3:58     ` Marek Vasut
  0 siblings, 1 reply; 21+ messages in thread
From: Richard Henderson @ 2016-09-29  1:05 UTC (permalink / raw)
  To: Marek Vasut, qemu-devel
  Cc: Jeff Da Silva, Chris Wulff, Sandra Loosemore, Yves Vandervennet,
	Ley Foon Tan

>  hw/nios2/cpu_pic.c         |   70 +++

Why is this in this patch?

>  target-nios2/instruction.c | 1427 ++++++++++++++++++++++++++++++++++++++++++++
>  target-nios2/instruction.h |  279 +++++++++
>  target-nios2/translate.c   |  242 ++++++++

Why are these files separate?

> +    if (n < 32)		/* GP regs */
> +        return gdb_get_reg32(mem_buf, env->regs[n]);
> +    else if (n == 32)	/* PC */
> +        return gdb_get_reg32(mem_buf, env->regs[R_PC]);
> +    else if (n < 49)	/* Status regs */
> +        return gdb_get_reg32(mem_buf, env->regs[n - 1]);

Use checkpatch.pl; the formatting is wrong.

There's no particular reason why R_PC needs to be 64; if you change it to 32, 
you can simplify this.

> +struct CPUNios2State {
> +    uint32_t regs[NUM_CORE_REGS];
> +
> +    /* Addresses that are hard-coded in the FPGA build settings */
> +    uint32_t reset_addr;
> +    uint32_t exception_addr;
> +    uint32_t fast_tlb_miss_addr;

These three should go after ...

> +
> +#if !defined(CONFIG_USER_ONLY)
> +    Nios2MMU mmu;
> +
> +    uint32_t irq_pending;
> +#endif
> +
> +    CPU_COMMON

... here, or even into ...

> +};
> +
> +/**
> + * Nios2CPU:
> + * @env: #CPUNios2State
> + *
> + * A Nios2 CPU.
> + */
> +typedef struct Nios2CPU {
> +    /*< private >*/
> +    CPUState parent_obj;
> +    /*< public >*/
> +
> +    CPUNios2State env;
> +    bool mmu_present;

... here.

> +static inline void t_gen_helper_raise_exception(DisasContext *dc,
> +                                                uint32_t index)

Remove all of the inline markers and let the compiler decide.

> +static void gen_check_supervisor(DisasContext *dc, TCGLabel *label)
> +{
> +    TCGLabel *l1 = gen_new_label();
> +
> +    TCGv_i32 tmp = tcg_temp_new();
> +    tcg_gen_andi_tl(tmp, dc->cpu_R[CR_STATUS], CR_STATUS_U);
> +    tcg_gen_brcond_tl(TCG_COND_EQ, dc->cpu_R[R_ZERO], tmp, l1);
> +    t_gen_helper_raise_exception(dc, EXCP_SUPERI);
> +    tcg_gen_br(label);

The supervisor check should be done at translate time by checking dc->tb->flags 
& CR_STATUS_U.

> +#ifdef CALL_TRACING
> +    TCGv_i32 tmp = tcg_const_i32(dc->pc);
> +    TCGv_i32 tmp2 = tcg_const_i32((dc->pc & 0xF0000000) | (instr->imm26 * 4));
> +    gen_helper_call_status(tmp, tmp2);
> +    tcg_temp_free_i32(tmp);
> +    tcg_temp_free_i32(tmp2);
> +#endif

What's the point of this?

> +/*
> + * I-Type instructions
> + */
> +
> +/* rB <- 0x000000 : Mem8[rA + @(IMM16)] */
> +static void ldbu(DisasContext *dc, uint32_t code)
> +{
> +    I_TYPE(instr, code);
> +
> +    TCGv addr = tcg_temp_new();
> +    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
> +                    (int32_t)((int16_t)instr->imm16));
> +
> +    tcg_gen_qemu_ld8u(dc->cpu_R[instr->b], addr, dc->mem_idx);
> +
> +    tcg_temp_free(addr);
> +}

You should have helper functions so that you don't have to replicate 12 line 
functions.  Use the tcg_gen_qemu_ld_tl function, and the TCGMemOp flags to help 
merge all load instructions, and all store instructions.

> +/* rB <- rA + IMM16 */
> +static void addi(DisasContext *dc, uint32_t code)
> +{
> +    I_TYPE(instr, code);
> +
> +    TCGv imm = tcg_temp_new();
> +    tcg_gen_addi_tl(dc->cpu_R[instr->b], dc->cpu_R[instr->a],
> +                    (int32_t)((int16_t)instr->imm16));

The double cast is pointless, as are the extra parenthesis.

You're not doing anything to make sure that r0 reads as 0, and ignores writes. 
You need to look at target-alpha, target-mips, or target-sparc to see various 
ways in which a zero register may be handled.

You should handle the special case of movi, documented as addi rb, r0, imm, so 
that the common method of loading a small value does not require extra tcg opcodes.

Similarly for the other (common) aliases, like mov and nop, which are both 
aliased to add.

> +/* Initializes the data cache line currently caching address rA + @(IMM16) */
> +static void initda(DisasContext *dc __attribute__((unused)),
> +                   uint32_t code __attribute__((unused)))
> +{
> +    /* TODO */
> +}

This will always be a nop for qemu.

> +static void blt(DisasContext *dc, uint32_t code)
> +{
> +    I_TYPE(instr, code);
> +
> +    TCGLabel *l1 = gen_new_label();
> +
> +    tcg_gen_brcond_tl(TCG_COND_LT, dc->cpu_R[instr->a],
> +                      dc->cpu_R[instr->b], l1);
> +
> +    gen_goto_tb(dc, 0, dc->pc + 4);
> +
> +    gen_set_label(l1);
> +
> +    gen_goto_tb(dc, 1, dc->pc + 4 + (int16_t)(instr->imm16 & 0xFFFC));
> +
> +    dc->is_jmp = DISAS_TB_JUMP;
> +}

These really require a helper function.

> +/* rB <- 0x000000 : Mem8[rA + @(IMM16)] (bypassing cache) */
> +static void ldbuio(DisasContext *dc, uint32_t code)

Reuse ldbu; qemu will never implement caches.

> +/* rB <- (rA * @(IMM16))(31..0) */
> +static void muli(DisasContext *dc, uint32_t code)
> +{
> +    I_TYPE(instr, code);
> +
> +    TCGv imm = tcg_temp_new();
> +    tcg_gen_muli_i32(dc->cpu_R[instr->b], dc->cpu_R[instr->a],
> +                     (int32_t)((int16_t)instr->imm16));
> +    tcg_temp_free(imm);

imm is unused.

> +static const Nios2Instruction i_type_instructions[I_TYPE_COUNT] = {
> +    [CALL]    = INSTRUCTION(call),
> +    [JMPI]    = INSTRUCTION(jmpi),
> +    [0x02]    = INSTRUCTION_ILLEGAL(),
> +    [LDBU]    = INSTRUCTION(ldbu),
> +    [ADDI]    = INSTRUCTION(addi),
> +    [STB]     = INSTRUCTION(stb),
> +    [BR]      = INSTRUCTION(br),
> +    [LDB]     = INSTRUCTION(ldb),
> +    [CMPGEI]  = INSTRUCTION(cmpgei),
> +    [0x09]    = INSTRUCTION_ILLEGAL(),
> +    [0x0a]    = INSTRUCTION_ILLEGAL(),
> +    [LDHU]    = INSTRUCTION(ldhu),
> +    [ANDI]    = INSTRUCTION(andi),
> +    [STH]     = INSTRUCTION(sth),
> +    [BGE]     = INSTRUCTION(bge),
> +    [LDH]     = INSTRUCTION(ldh),
> +    [CMPLTI]  = INSTRUCTION(cmplti),
> +    [0x11]    = INSTRUCTION_ILLEGAL(),
> +    [0x12]    = INSTRUCTION_ILLEGAL(),
> +    [INITDA]  = INSTRUCTION(initda),
> +    [ORI]     = INSTRUCTION(ori),
> +    [STW]     = INSTRUCTION(stw),
> +    [BLT]     = INSTRUCTION(blt),
> +    [LDW]     = INSTRUCTION(ldw),
> +    [CMPNEI]  = INSTRUCTION(cmpnei),
> +    [0x19]    = INSTRUCTION_ILLEGAL(),
> +    [0x1a]    = INSTRUCTION_ILLEGAL(),
> +    [FLUSHDA] = INSTRUCTION_NOP(flushda),
> +    [XORI]    = INSTRUCTION(xori),
> +    [0x1d]    = INSTRUCTION_ILLEGAL(),
> +    [BNE]     = INSTRUCTION(bne),
> +    [0x1f]    = INSTRUCTION_ILLEGAL(),
> +    [CMPEQI]  = INSTRUCTION(cmpeqi),
> +    [0x21]    = INSTRUCTION_ILLEGAL(),
> +    [0x22]    = INSTRUCTION_ILLEGAL(),
> +    [LDBUIO]  = INSTRUCTION(ldbuio),
> +    [MULI]    = INSTRUCTION(muli),
> +    [STBIO]   = INSTRUCTION(stbio),
> +    [BEQ]     = INSTRUCTION(beq),
> +    [LDBIO]   = INSTRUCTION(ldbio),
> +    [CMPGEUI] = INSTRUCTION(cmpgeui),
> +    [0x29]    = INSTRUCTION_ILLEGAL(),
> +    [0x2a]    = INSTRUCTION_ILLEGAL(),
> +    [LDHUIO]  = INSTRUCTION(ldhuio),
> +    [ANDHI]   = INSTRUCTION(andhi),
> +    [STHIO]   = INSTRUCTION(sthio),
> +    [BGEU]    = INSTRUCTION(bgeu),
> +    [LDHIO]   = INSTRUCTION(ldhio),
> +    [CMPLTUI] = INSTRUCTION(cmpltui),
> +    [0x31]    = INSTRUCTION_ILLEGAL(),
> +    [CUSTOM]  = INSTRUCTION_UNIMPLEMENTED(custom),
> +    [INITD]   = INSTRUCTION(initd),
> +    [ORHI]    = INSTRUCTION(orhi),
> +    [STWIO]   = INSTRUCTION(stwio),
> +    [BLTU]    = INSTRUCTION(bltu),
> +    [LDWIO]   = INSTRUCTION(ldwio),
> +    [RDPRS]   = INSTRUCTION_UNIMPLEMENTED(rdprs),
> +    [0x39]    = INSTRUCTION_ILLEGAL(),
> +    [R_TYPE]  = { "<R-type instruction>", handle_r_type_instr },
> +    [FLUSHD]  = INSTRUCTION_NOP(flushd),
> +    [XORHI]   = INSTRUCTION(xorhi),
> +    [0x3d]    = INSTRUCTION_ILLEGAL(),
> +    [0x3e]    = INSTRUCTION_ILLEGAL(),
> +    [0x3f]    = INSTRUCTION_ILLEGAL(),

Is there really any point to using a table, as opposed to a switch statement? 
At least with a switch you can use default to catch all of the illegals at once.

> +/* rC <- ((unsigned)rA * (unsigned)rB))(31..0) */
> +static void mulxuu(DisasContext *dc, uint32_t code)
> +{
> +    R_TYPE(instr, code);
> +
> +    TCGv_i64 t0, t1;
> +
> +    t0 = tcg_temp_new_i64();
> +    t1 = tcg_temp_new_i64();
> +
> +    tcg_gen_extu_i32_i64(t0, dc->cpu_R[instr->a]);
> +    tcg_gen_extu_i32_i64(t1, dc->cpu_R[instr->b]);
> +    tcg_gen_mul_i64(t0, t0, t1);
> +
> +    tcg_gen_shri_i64(t0, t0, 32);
> +    tcg_gen_extrl_i64_i32(dc->cpu_R[instr->c], t0);

   TCGv t0 = tcg_temp_new();
   tcg_gen_mulu2_tl(t0, dc->cpu_R[instr->c],
                    dc->cpu_R[instr->a],
                    dc->cpu_R[instr->b]);
   tcg_temp_free(t0);

> +/* rC <- ((signed)rA * (unsigned)rB))(31..0) */
> +static void mulxsu(DisasContext *dc, uint32_t code)
> +{
> +    R_TYPE(instr, code);
> +
> +    TCGv_i64 t0, t1;
> +
> +    t0 = tcg_temp_new_i64();
> +    t1 = tcg_temp_new_i64();
> +
> +    tcg_gen_ext_i32_i64(t0, dc->cpu_R[instr->a]);
> +    tcg_gen_extu_i32_i64(t1, dc->cpu_R[instr->b]);
> +    tcg_gen_mul_i64(t0, t0, t1);
> +
> +    tcg_gen_shri_i64(t0, t0, 32);
> +    tcg_gen_extrl_i64_i32(dc->cpu_R[instr->c], t0);

Similarly, using tcg_gen_mulsu2_tl.  To be fair, a patch for this was posted 
yesterday, and will be included in a tcg pull soon.  See

   https://patchwork.ozlabs.org/patch/675859/

> +static void callr(DisasContext *dc, uint32_t code)
> +{
> +    R_TYPE(instr, code);
> +
> +#ifdef CALL_TRACING
> +    TCGv_i32 tmp = tcg_const_i32(dc->pc);
> +    gen_helper_call_status(tmp, dc->cpu_R[instr->a]);
> +    tcg_temp_free_i32(tmp);
> +#endif
> +
> +    tcg_gen_movi_tl(dc->cpu_R[R_RA], dc->pc + 4);
> +    tcg_gen_mov_tl(dc->cpu_R[R_PC], dc->cpu_R[instr->a]);

Does the hardware actually prevent rA == RA like this?  The documentation is 
unclear.  If the hardware actually performs the described actions in parallel, 
then you need to swap these two lines.

> +/* rC <- ((signed)rA * (signed)rB))(31..0) */
> +static void mulxss(DisasContext *dc, uint32_t code)
> +{
> +    R_TYPE(instr, code);
> +
> +    TCGv_i64 t0, t1;
> +
> +    t0 = tcg_temp_new_i64();
> +    t1 = tcg_temp_new_i64();
> +
> +    tcg_gen_ext_i32_i64(t0, dc->cpu_R[instr->a]);
> +    tcg_gen_ext_i32_i64(t1, dc->cpu_R[instr->b]);
> +    tcg_gen_mul_i64(t0, t0, t1);

Similarly, tcg_gen_muls2_tl.

> +/* rC <- rA / rB */
> +static void divu(DisasContext *dc, uint32_t code)
> +{
> +    R_TYPE(instr, code);
> +
> +    gen_helper_divu(dc->cpu_R[instr->c], dc->cpu_R[instr->a],
> +                    dc->cpu_R[instr->b]);
> +}

You can perform this inline.  C.f. target-mips

Since divide-by-zero is undefined, this can be done with

   TCGv t0 = tcg_const_tl(0);
   tcg_gen_setcond_tl(TCG_COND_EQ, t0, dc->cpu_R[instr->b], t0);
   tcg_gen_or_tl(t0, t0, dc->cpu_R[instr->b]);
   tcg_gen_divu_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], t0);
   tcg_temp_free_tl(t0);

> +    gen_helper_divs(dc->cpu_R[instr->c], dc->cpu_R[instr->a],
> +                    dc->cpu_R[instr->b]);

Similarly.

> +/*
> + * bstatus ← status
> + * PIE <- 0
> + * U <- 0
> + * ba <- PC + 4
> + * PC <- break handler address
> + */
> +static void __break(DisasContext *dc, uint32_t code __attribute__((unused)))

This symbol is in the system namespace.  Just use break_insn or something.

> +static const Nios2Instruction r_type_instructions[R_TYPE_COUNT] = {
> +    [0x00]   = INSTRUCTION_ILLEGAL(),
> +    [ERET]   = INSTRUCTION(eret),
> +    [ROLI]   = INSTRUCTION(roli),
> +    [ROL]    = INSTRUCTION(rol),
> +    [FLUSHP] = INSTRUCTION(flushp),
> +    [RET]    = INSTRUCTION(ret),
> +    [NOR]    = INSTRUCTION(nor),
> +    [MULXUU] = INSTRUCTION(mulxuu),
> +    [CMPGE]  = INSTRUCTION(cmpge),
> +    [BRET]   = INSTRUCTION(bret),
> +    [0x0a]   = INSTRUCTION_ILLEGAL(),
> +    [ROR]    = INSTRUCTION(ror),
> +    [FLUSHI] = INSTRUCTION(flushi),
> +    [JMP]    = INSTRUCTION(jmp),
> +    [AND]    = INSTRUCTION(and),
> +    [0x0f]   = INSTRUCTION_ILLEGAL(),
> +    [CMPLT]  = INSTRUCTION(cmplt),
> +    [0x11]   = INSTRUCTION_ILLEGAL(),
> +    [SLLI]   = INSTRUCTION(slli),
> +    [SLL]    = INSTRUCTION(sll),
> +    [WRPRS]  = INSTRUCTION_UNIMPLEMENTED(wrprs),
> +    [0x15]   = INSTRUCTION_ILLEGAL(),
> +    [OR]     = INSTRUCTION(or),
> +    [MULXSU] = INSTRUCTION(mulxsu),
> +    [CMPNE]  = INSTRUCTION(cmpne),
> +    [0x19]   = INSTRUCTION_ILLEGAL(),
> +    [SRLI]   = INSTRUCTION(srli),
> +    [SRL]    = INSTRUCTION(srl),
> +    [NEXTPC] = INSTRUCTION(nextpc),
> +    [CALLR]  = INSTRUCTION(callr),
> +    [XOR]    = INSTRUCTION(xor),
> +    [MULXSS] = INSTRUCTION(mulxss),
> +    [CMPEQ]  = INSTRUCTION(cmpeq),
> +    [0x21]   = INSTRUCTION_ILLEGAL(),
> +    [0x22]   = INSTRUCTION_ILLEGAL(),
> +    [0x23]   = INSTRUCTION_ILLEGAL(),
> +    [DIVU]   = INSTRUCTION(divu),
> +    [DIV]    = { "div", _div },
> +    [RDCTL]  = INSTRUCTION(rdctl),
> +    [MUL]    = INSTRUCTION(mul),
> +    [CMPGEU] = INSTRUCTION(cmpgeu),
> +    [INITI]  = INSTRUCTION(initi),
> +    [0x2a]   = INSTRUCTION_ILLEGAL(),
> +    [0x2b]   = INSTRUCTION_ILLEGAL(),
> +    [0x2c]   = INSTRUCTION_ILLEGAL(),
> +    [TRAP]   = INSTRUCTION(trap),
> +    [WRCTL]  = INSTRUCTION(wrctl),
> +    [0x2f]   = INSTRUCTION_ILLEGAL(),
> +    [CMPLTU] = INSTRUCTION(cmpltu),
> +    [ADD]    = INSTRUCTION(add),
> +    [0x32]   = INSTRUCTION_ILLEGAL(),
> +    [0x33]   = INSTRUCTION_ILLEGAL(),
> +    [BREAK]  = { "break", __break },
> +    [0x35]   = INSTRUCTION_ILLEGAL(),
> +    [SYNC]   = INSTRUCTION(nop),
> +    [0x37]   = INSTRUCTION_ILLEGAL(),
> +    [0x38]   = INSTRUCTION_ILLEGAL(),
> +    [SUB]    = INSTRUCTION(sub),
> +    [SRAI]   = INSTRUCTION(srai),
> +    [SRA]    = INSTRUCTION(sra),
> +    [0x3c]   = INSTRUCTION_ILLEGAL(),
> +    [0x3d]   = INSTRUCTION_ILLEGAL(),
> +    [0x3e]   = INSTRUCTION_ILLEGAL(),
> +    [0x3f]   = INSTRUCTION_ILLEGAL(),
> +};

Similar comment wrt the I-type table.

> +const char *instruction_get_string(uint32_t code)
> +{
> +    uint32_t op = get_opcode(code);
> +
> +    if (unlikely(op >= I_TYPE_COUNT)) {
> +        return "";
> +    } else if (op == R_TYPE) {
> +        uint32_t opx = get_opxcode(code);
> +        if (unlikely(opx >= R_TYPE_COUNT)) {
> +            return "";
> +        }
> +        return r_type_instructions[opx].name;
> +    } else {
> +        return i_type_instructions[op].name;
> +    }
> +}

What is this function used for?

> +/* I-Type instruction */
> +typedef struct Nios2IType {
> +    uint32_t op:6;
> +    uint32_t imm16:16;
> +    uint32_t b:5;
> +    uint32_t a:5;
> +} QEMU_PACKED Nios2IType;

These bitfields are a non-starter.  Layout of them is non-portable in more ways 
than is worth going into here.  You must use extract32 and sextract32 to 
extract the fields.

> +
> +union i_type_u {
> +    uint32_t      v;
> +    Nios2IType i;
> +};
> +
> +#define I_TYPE(instr, op) \
> +    union i_type_u instr_u = { .v = op }; \
> +    Nios2IType *instr = &instr_u.i

You could probably still hide everything behind this macro, with an inline 
function returning a structure (defined *without* bitfields).

> +/*
> + * Return values for instruction handlers
> + */
> +#define INSTR_UNIMPL     -2  /* Unimplemented instruction */
> +#define INSTR_ERR        -1  /* Error in instruction */
> +#define PC_INC_NORMAL     0  /* Normal PC increment after instruction */
> +#define PC_INC_BY_INSTR   1  /* PC got incremented by instruction */
> +#define INSTR_BREAK       2  /* Break encountered */
> +#define INSTR_EXCEPTION 255  /* Instruction generated an exception
> +                                (the exception cause will be stored
> +                                in struct nios2 */

What's the gain over using a simple enum with sequential values?

> +/*
> + * FIXME: Convert to VMstate
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/hw.h"
> +#include "hw/boards.h"
> +
> +void cpu_save(QEMUFile *f, void *opaque)
> +{
> +    /* TODO */
> +}
> +
> +int cpu_load(QEMUFile *f, void *opaque, int version_id)
> +{
> +    /* TODO */
> +    return 0;
> +}

Fixing this is no longer optional.

> +void helper_memalign(CPUNios2State *env, uint32_t addr, uint32_t dr, uint32_t wr, uint32_t mask)
> +{
> +    if (addr & mask) {
> +        qemu_log("unaligned access addr=%x mask=%x, wr=%d dr=r%d\n",
> +                 addr, mask, wr, dr);
> +        env->regs[CR_BADADDR] = addr;
> +        env->regs[CR_EXCEPTION] = EXCP_UNALIGN << 2;
> +        helper_raise_exception(env, EXCP_UNALIGN);
> +    }
> +}

What is this doing that cc->do_unaligned_access doesn't?

> +    /* Initialize DC */
> +    dc->cpu_env = cpu_env;
> +    dc->cpu_R   = cpu_R;

What is this assignment for?  Are you planning to implement shadow registers at 
some point?


r~

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [V2,1/7] nios2: Add disas entries
  2016-09-27 23:30 [Qemu-devel] [PATCH V2 1/7] nios2: Add disas entries Marek Vasut
                   ` (5 preceding siblings ...)
  2016-09-27 23:30 ` [Qemu-devel] [PATCH 7/7] nios2: Add support for Nios-II R1 Marek Vasut
@ 2016-10-15 13:15 ` Romain Naour
  2016-10-18  4:17   ` Marek Vasut
  6 siblings, 1 reply; 21+ messages in thread
From: Romain Naour @ 2016-10-15 13:15 UTC (permalink / raw)
  To: Marek Vasut, qemu-devel
  Cc: Jeff Da Silva, Chris Wulff, Sandra Loosemore, Yves Vandervennet,
	Ley Foon Tan, Waldemar Brodkorb

Hi Marek,

Le 28/09/2016 à 01:30, Marek Vasut a écrit :
> Add nios2 disassembler support. This patch is composed from binutils files
> from commit "Opcodes and assembler support for Nios II R2". The files from
> binutils used in this patch are:
> 
>     include/opcode/nios2.h
>     include/opcode/nios2r1.h
>     include/opcode/nios2r2.h
>     opcodes/nios2-opc.c
>     opcodes/nios2-dis.c

With Waldemar Brodkorb and I, we tested this series using 10m50 kernel defconfig
with Buildroot generated system. In order to ease the test, we added the device
tree and a initramfs to the kernel image.

Here is the result:

Welcome to Buildroot
# cat /proc/cpuinfo
CPU:		Nios II/fast
MMU:		present
FPU:		none
Clocking:	75.00 MHz
BogoMips:	150.00
Calibration:	75000000 loops
HW:
 MUL:		yes
 MULX:		no
 DIV:		yes
Icache:		32kB, line length: 32
Dcache:		32kB, line length: 32
TLB:		16 ways, 256 entries, 8 PID bits
# uname -a
Linux buildroot 4.8.1 #2 Fri Oct 14 19:10:18 CEST 2016 nios2 GNU/Linux

When this series will be accepted in Qemu, I'll add a demo defconfig in
Buildroot in order to ease runtime testing.

Tested-by: Romain Naour <romain.naour@gmail.com>

Best regards,
Romain

> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Chris Wulff <crwulff@gmail.com>
> Cc: Jeff Da Silva <jdasilva@altera.com>
> Cc: Ley Foon Tan <lftan@altera.com>
> Cc: Sandra Loosemore <sandra@codesourcery.com>
> Cc: Yves Vandervennet <yvanderv@altera.com>
> ---
> V2: Replace the nios2.c with GPL2 licensed version
> ---

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support
  2016-09-29  1:05   ` Richard Henderson
@ 2016-10-18  3:58     ` Marek Vasut
  2016-10-18 15:31       ` Richard Henderson
  0 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2016-10-18  3:58 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: Jeff Da Silva, Chris Wulff, Sandra Loosemore, Yves Vandervennet,
	Ley Foon Tan

On 09/29/2016 03:05 AM, Richard Henderson wrote:
>>  hw/nios2/cpu_pic.c         |   70 +++
> 
> Why is this in this patch?

Ah, good catch, moved to 10m50 support patch.

>>  target-nios2/instruction.c | 1427
>> ++++++++++++++++++++++++++++++++++++++++++++
>>  target-nios2/instruction.h |  279 +++++++++
>>  target-nios2/translate.c   |  242 ++++++++
> 
> Why are these files separate?

Remnant of the old code, will merge them.

>> +    if (n < 32)        /* GP regs */
>> +        return gdb_get_reg32(mem_buf, env->regs[n]);
>> +    else if (n == 32)    /* PC */
>> +        return gdb_get_reg32(mem_buf, env->regs[R_PC]);
>> +    else if (n < 49)    /* Status regs */
>> +        return gdb_get_reg32(mem_buf, env->regs[n - 1]);
> 
> Use checkpatch.pl; the formatting is wrong.

Fixed across the entire series, thanks.

> There's no particular reason why R_PC needs to be 64; if you change it
> to 32, you can simplify this.

I believe this is in fact needed, see [1] page 18 (section 2, Register
file), quote:

"
The Nios II architecture supports a flat register file, consisting of
thirty-two 32-bit general-purpose integer
registers, and up to thirty-two 32-bit control registers. The
architecture supports supervisor and user
modes that allow system code to protect the control registers from
errant applications.
"

So the CPU supports 32 general purpose regs (R_ZERO..R_RA), then up-to
32 Control registers (CR_STATUS..CR_MPUACC) and then the PC .


[1]
https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/hb/nios2/n2cpu_nii5v1.pdf

>> +struct CPUNios2State {
>> +    uint32_t regs[NUM_CORE_REGS];
>> +
>> +    /* Addresses that are hard-coded in the FPGA build settings */
>> +    uint32_t reset_addr;
>> +    uint32_t exception_addr;
>> +    uint32_t fast_tlb_miss_addr;
> 
> These three should go after ...
> 
>> +
>> +#if !defined(CONFIG_USER_ONLY)
>> +    Nios2MMU mmu;
>> +
>> +    uint32_t irq_pending;
>> +#endif
>> +
>> +    CPU_COMMON
> 
> ... here, or even into ...
> 
>> +};
>> +
>> +/**
>> + * Nios2CPU:
>> + * @env: #CPUNios2State
>> + *
>> + * A Nios2 CPU.
>> + */
>> +typedef struct Nios2CPU {
>> +    /*< private >*/
>> +    CPUState parent_obj;
>> +    /*< public >*/
>> +
>> +    CPUNios2State env;
>> +    bool mmu_present;
> 
> ... here.

Moved here, it looks more sensible as it's not something one can change
at runtime.

>> +static inline void t_gen_helper_raise_exception(DisasContext *dc,
>> +                                                uint32_t index)
> 
> Remove all of the inline markers and let the compiler decide.

Done globally, thanks.

>> +static void gen_check_supervisor(DisasContext *dc, TCGLabel *label)
>> +{
>> +    TCGLabel *l1 = gen_new_label();
>> +
>> +    TCGv_i32 tmp = tcg_temp_new();
>> +    tcg_gen_andi_tl(tmp, dc->cpu_R[CR_STATUS], CR_STATUS_U);
>> +    tcg_gen_brcond_tl(TCG_COND_EQ, dc->cpu_R[R_ZERO], tmp, l1);
>> +    t_gen_helper_raise_exception(dc, EXCP_SUPERI);
>> +    tcg_gen_br(label);
> 
> The supervisor check should be done at translate time by checking
> dc->tb->flags & CR_STATUS_U.

Fixed.

>> +#ifdef CALL_TRACING
>> +    TCGv_i32 tmp = tcg_const_i32(dc->pc);
>> +    TCGv_i32 tmp2 = tcg_const_i32((dc->pc & 0xF0000000) |
>> (instr->imm26 * 4));
>> +    gen_helper_call_status(tmp, tmp2);
>> +    tcg_temp_free_i32(tmp);
>> +    tcg_temp_free_i32(tmp2);
>> +#endif
> 
> What's the point of this?

Seems like some stale debug helper, removed, thanks.

>> +/*
>> + * I-Type instructions
>> + */
>> +
>> +/* rB <- 0x000000 : Mem8[rA + @(IMM16)] */
>> +static void ldbu(DisasContext *dc, uint32_t code)
>> +{
>> +    I_TYPE(instr, code);
>> +
>> +    TCGv addr = tcg_temp_new();
>> +    tcg_gen_addi_tl(addr, dc->cpu_R[instr->a],
>> +                    (int32_t)((int16_t)instr->imm16));
>> +
>> +    tcg_gen_qemu_ld8u(dc->cpu_R[instr->b], addr, dc->mem_idx);
>> +
>> +    tcg_temp_free(addr);
>> +}
> 
> You should have helper functions so that you don't have to replicate 12
> line functions.  Use the tcg_gen_qemu_ld_tl function, and the TCGMemOp
> flags to help merge all load instructions, and all store instructions.

Oh nice, thanks.

>> +/* rB <- rA + IMM16 */
>> +static void addi(DisasContext *dc, uint32_t code)
>> +{
>> +    I_TYPE(instr, code);
>> +
>> +    TCGv imm = tcg_temp_new();
>> +    tcg_gen_addi_tl(dc->cpu_R[instr->b], dc->cpu_R[instr->a],
>> +                    (int32_t)((int16_t)instr->imm16));
> 
> The double cast is pointless, as are the extra parenthesis.

The int16_t cast is needed as the imm16 is signed value. The int32()
cast is indeed pointless, so removed. Thanks.

> You're not doing anything to make sure that r0 reads as 0, and ignores
> writes. You need to look at target-alpha, target-mips, or target-sparc
> to see various ways in which a zero register may be handled.

Any hint on this one ?

> You should handle the special case of movi, documented as addi rb, r0,
> imm, so that the common method of loading a small value does not require
> extra tcg opcodes.
> 
> Similarly for the other (common) aliases, like mov and nop, which are
> both aliased to add.

Fixed

>> +/* Initializes the data cache line currently caching address rA +
>> @(IMM16) */
>> +static void initda(DisasContext *dc __attribute__((unused)),
>> +                   uint32_t code __attribute__((unused)))
>> +{
>> +    /* TODO */
>> +}
> 
> This will always be a nop for qemu.

Replaced with NOP instructions.

>> +static void blt(DisasContext *dc, uint32_t code)
>> +{
>> +    I_TYPE(instr, code);
>> +
>> +    TCGLabel *l1 = gen_new_label();
>> +
>> +    tcg_gen_brcond_tl(TCG_COND_LT, dc->cpu_R[instr->a],
>> +                      dc->cpu_R[instr->b], l1);
>> +
>> +    gen_goto_tb(dc, 0, dc->pc + 4);
>> +
>> +    gen_set_label(l1);
>> +
>> +    gen_goto_tb(dc, 1, dc->pc + 4 + (int16_t)(instr->imm16 & 0xFFFC));
>> +
>> +    dc->is_jmp = DISAS_TB_JUMP;
>> +}
> 
> These really require a helper function.

Yes, fixed.

>> +/* rB <- 0x000000 : Mem8[rA + @(IMM16)] (bypassing cache) */
>> +static void ldbuio(DisasContext *dc, uint32_t code)
> 
> Reuse ldbu; qemu will never implement caches.
> 
>> +/* rB <- (rA * @(IMM16))(31..0) */
>> +static void muli(DisasContext *dc, uint32_t code)
>> +{
>> +    I_TYPE(instr, code);
>> +
>> +    TCGv imm = tcg_temp_new();
>> +    tcg_gen_muli_i32(dc->cpu_R[instr->b], dc->cpu_R[instr->a],
>> +                     (int32_t)((int16_t)instr->imm16));
>> +    tcg_temp_free(imm);
> 
> imm is unused.

I reworked this some more, so fixed.

>> +static const Nios2Instruction i_type_instructions[I_TYPE_COUNT] = {
>> +    [CALL]    = INSTRUCTION(call),
>> +    [JMPI]    = INSTRUCTION(jmpi),
>> +    [0x02]    = INSTRUCTION_ILLEGAL(),
>> +    [LDBU]    = INSTRUCTION(ldbu),
>> +    [ADDI]    = INSTRUCTION(addi),
>> +    [STB]     = INSTRUCTION(stb),
>> +    [BR]      = INSTRUCTION(br),
>> +    [LDB]     = INSTRUCTION(ldb),
>> +    [CMPGEI]  = INSTRUCTION(cmpgei),
>> +    [0x09]    = INSTRUCTION_ILLEGAL(),
>> +    [0x0a]    = INSTRUCTION_ILLEGAL(),
>> +    [LDHU]    = INSTRUCTION(ldhu),
>> +    [ANDI]    = INSTRUCTION(andi),
>> +    [STH]     = INSTRUCTION(sth),
>> +    [BGE]     = INSTRUCTION(bge),
>> +    [LDH]     = INSTRUCTION(ldh),
>> +    [CMPLTI]  = INSTRUCTION(cmplti),
>> +    [0x11]    = INSTRUCTION_ILLEGAL(),
>> +    [0x12]    = INSTRUCTION_ILLEGAL(),
>> +    [INITDA]  = INSTRUCTION(initda),
>> +    [ORI]     = INSTRUCTION(ori),
>> +    [STW]     = INSTRUCTION(stw),
>> +    [BLT]     = INSTRUCTION(blt),
>> +    [LDW]     = INSTRUCTION(ldw),
>> +    [CMPNEI]  = INSTRUCTION(cmpnei),
>> +    [0x19]    = INSTRUCTION_ILLEGAL(),
>> +    [0x1a]    = INSTRUCTION_ILLEGAL(),
>> +    [FLUSHDA] = INSTRUCTION_NOP(flushda),
>> +    [XORI]    = INSTRUCTION(xori),
>> +    [0x1d]    = INSTRUCTION_ILLEGAL(),
>> +    [BNE]     = INSTRUCTION(bne),
>> +    [0x1f]    = INSTRUCTION_ILLEGAL(),
>> +    [CMPEQI]  = INSTRUCTION(cmpeqi),
>> +    [0x21]    = INSTRUCTION_ILLEGAL(),
>> +    [0x22]    = INSTRUCTION_ILLEGAL(),
>> +    [LDBUIO]  = INSTRUCTION(ldbuio),
>> +    [MULI]    = INSTRUCTION(muli),
>> +    [STBIO]   = INSTRUCTION(stbio),
>> +    [BEQ]     = INSTRUCTION(beq),
>> +    [LDBIO]   = INSTRUCTION(ldbio),
>> +    [CMPGEUI] = INSTRUCTION(cmpgeui),
>> +    [0x29]    = INSTRUCTION_ILLEGAL(),
>> +    [0x2a]    = INSTRUCTION_ILLEGAL(),
>> +    [LDHUIO]  = INSTRUCTION(ldhuio),
>> +    [ANDHI]   = INSTRUCTION(andhi),
>> +    [STHIO]   = INSTRUCTION(sthio),
>> +    [BGEU]    = INSTRUCTION(bgeu),
>> +    [LDHIO]   = INSTRUCTION(ldhio),
>> +    [CMPLTUI] = INSTRUCTION(cmpltui),
>> +    [0x31]    = INSTRUCTION_ILLEGAL(),
>> +    [CUSTOM]  = INSTRUCTION_UNIMPLEMENTED(custom),
>> +    [INITD]   = INSTRUCTION(initd),
>> +    [ORHI]    = INSTRUCTION(orhi),
>> +    [STWIO]   = INSTRUCTION(stwio),
>> +    [BLTU]    = INSTRUCTION(bltu),
>> +    [LDWIO]   = INSTRUCTION(ldwio),
>> +    [RDPRS]   = INSTRUCTION_UNIMPLEMENTED(rdprs),
>> +    [0x39]    = INSTRUCTION_ILLEGAL(),
>> +    [R_TYPE]  = { "<R-type instruction>", handle_r_type_instr },
>> +    [FLUSHD]  = INSTRUCTION_NOP(flushd),
>> +    [XORHI]   = INSTRUCTION(xorhi),
>> +    [0x3d]    = INSTRUCTION_ILLEGAL(),
>> +    [0x3e]    = INSTRUCTION_ILLEGAL(),
>> +    [0x3f]    = INSTRUCTION_ILLEGAL(),
> 
> Is there really any point to using a table, as opposed to a switch
> statement? At least with a switch you can use default to catch all of
> the illegals at once.

I don't need to track the instructions encodings separately, since the
NIOS2 only supports 40 I-/R-instructions .

>> +/* rC <- ((unsigned)rA * (unsigned)rB))(31..0) */
>> +static void mulxuu(DisasContext *dc, uint32_t code)
>> +{
>> +    R_TYPE(instr, code);
>> +
>> +    TCGv_i64 t0, t1;
>> +
>> +    t0 = tcg_temp_new_i64();
>> +    t1 = tcg_temp_new_i64();
>> +
>> +    tcg_gen_extu_i32_i64(t0, dc->cpu_R[instr->a]);
>> +    tcg_gen_extu_i32_i64(t1, dc->cpu_R[instr->b]);
>> +    tcg_gen_mul_i64(t0, t0, t1);
>> +
>> +    tcg_gen_shri_i64(t0, t0, 32);
>> +    tcg_gen_extrl_i64_i32(dc->cpu_R[instr->c], t0);
> 
>   TCGv t0 = tcg_temp_new();
>   tcg_gen_mulu2_tl(t0, dc->cpu_R[instr->c],
>                    dc->cpu_R[instr->a],
>                    dc->cpu_R[instr->b]);
>   tcg_temp_free(t0);
> 
>> +/* rC <- ((signed)rA * (unsigned)rB))(31..0) */
>> +static void mulxsu(DisasContext *dc, uint32_t code)
>> +{
>> +    R_TYPE(instr, code);
>> +
>> +    TCGv_i64 t0, t1;
>> +
>> +    t0 = tcg_temp_new_i64();
>> +    t1 = tcg_temp_new_i64();
>> +
>> +    tcg_gen_ext_i32_i64(t0, dc->cpu_R[instr->a]);
>> +    tcg_gen_extu_i32_i64(t1, dc->cpu_R[instr->b]);
>> +    tcg_gen_mul_i64(t0, t0, t1);
>> +
>> +    tcg_gen_shri_i64(t0, t0, 32);
>> +    tcg_gen_extrl_i64_i32(dc->cpu_R[instr->c], t0);
> 
> Similarly, using tcg_gen_mulsu2_tl.  To be fair, a patch for this was
> posted yesterday, and will be included in a tcg pull soon.  See
> 
>   https://patchwork.ozlabs.org/patch/675859/

Oh, nice, I picked this patch and replaced all those mulx*() functions.

>> +static void callr(DisasContext *dc, uint32_t code)
>> +{
>> +    R_TYPE(instr, code);
>> +
>> +#ifdef CALL_TRACING
>> +    TCGv_i32 tmp = tcg_const_i32(dc->pc);
>> +    gen_helper_call_status(tmp, dc->cpu_R[instr->a]);
>> +    tcg_temp_free_i32(tmp);
>> +#endif
>> +
>> +    tcg_gen_movi_tl(dc->cpu_R[R_RA], dc->pc + 4);
>> +    tcg_gen_mov_tl(dc->cpu_R[R_PC], dc->cpu_R[instr->a]);
> 
> Does the hardware actually prevent rA == RA like this?  The
> documentation is unclear.  If the hardware actually performs the
> described actions in parallel, then you need to swap these two lines.

That would only make sense, so swapped.

>> +/* rC <- ((signed)rA * (signed)rB))(31..0) */
>> +static void mulxss(DisasContext *dc, uint32_t code)
>> +{
>> +    R_TYPE(instr, code);
>> +
>> +    TCGv_i64 t0, t1;
>> +
>> +    t0 = tcg_temp_new_i64();
>> +    t1 = tcg_temp_new_i64();
>> +
>> +    tcg_gen_ext_i32_i64(t0, dc->cpu_R[instr->a]);
>> +    tcg_gen_ext_i32_i64(t1, dc->cpu_R[instr->b]);
>> +    tcg_gen_mul_i64(t0, t0, t1);
> 
> Similarly, tcg_gen_muls2_tl.

Fixed.

>> +/* rC <- rA / rB */
>> +static void divu(DisasContext *dc, uint32_t code)
>> +{
>> +    R_TYPE(instr, code);
>> +
>> +    gen_helper_divu(dc->cpu_R[instr->c], dc->cpu_R[instr->a],
>> +                    dc->cpu_R[instr->b]);
>> +}
> 
> You can perform this inline.  C.f. target-mips
> 
> Since divide-by-zero is undefined, this can be done with
> 
>   TCGv t0 = tcg_const_tl(0);
>   tcg_gen_setcond_tl(TCG_COND_EQ, t0, dc->cpu_R[instr->b], t0);
>   tcg_gen_or_tl(t0, t0, dc->cpu_R[instr->b]);
>   tcg_gen_divu_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], t0);
>   tcg_temp_free_tl(t0);

Just so I get it completely, isn't this handled somehow by the
tcg_gen_divu_tl() itself ?

>> +    gen_helper_divs(dc->cpu_R[instr->c], dc->cpu_R[instr->a],
>> +                    dc->cpu_R[instr->b]);
> 
> Similarly.

Fixed

>> +/*
>> + * bstatus ← status
>> + * PIE <- 0
>> + * U <- 0
>> + * ba <- PC + 4
>> + * PC <- break handler address
>> + */
>> +static void __break(DisasContext *dc, uint32_t code
>> __attribute__((unused)))
> 
> This symbol is in the system namespace.  Just use break_insn or something.

Fixed

>> +static const Nios2Instruction r_type_instructions[R_TYPE_COUNT] = {
>> +    [0x00]   = INSTRUCTION_ILLEGAL(),
>> +    [ERET]   = INSTRUCTION(eret),
>> +    [ROLI]   = INSTRUCTION(roli),
>> +    [ROL]    = INSTRUCTION(rol),
>> +    [FLUSHP] = INSTRUCTION(flushp),
>> +    [RET]    = INSTRUCTION(ret),
>> +    [NOR]    = INSTRUCTION(nor),
>> +    [MULXUU] = INSTRUCTION(mulxuu),
>> +    [CMPGE]  = INSTRUCTION(cmpge),
>> +    [BRET]   = INSTRUCTION(bret),
>> +    [0x0a]   = INSTRUCTION_ILLEGAL(),
>> +    [ROR]    = INSTRUCTION(ror),
>> +    [FLUSHI] = INSTRUCTION(flushi),
>> +    [JMP]    = INSTRUCTION(jmp),
>> +    [AND]    = INSTRUCTION(and),
>> +    [0x0f]   = INSTRUCTION_ILLEGAL(),
>> +    [CMPLT]  = INSTRUCTION(cmplt),
>> +    [0x11]   = INSTRUCTION_ILLEGAL(),
>> +    [SLLI]   = INSTRUCTION(slli),
>> +    [SLL]    = INSTRUCTION(sll),
>> +    [WRPRS]  = INSTRUCTION_UNIMPLEMENTED(wrprs),
>> +    [0x15]   = INSTRUCTION_ILLEGAL(),
>> +    [OR]     = INSTRUCTION(or),
>> +    [MULXSU] = INSTRUCTION(mulxsu),
>> +    [CMPNE]  = INSTRUCTION(cmpne),
>> +    [0x19]   = INSTRUCTION_ILLEGAL(),
>> +    [SRLI]   = INSTRUCTION(srli),
>> +    [SRL]    = INSTRUCTION(srl),
>> +    [NEXTPC] = INSTRUCTION(nextpc),
>> +    [CALLR]  = INSTRUCTION(callr),
>> +    [XOR]    = INSTRUCTION(xor),
>> +    [MULXSS] = INSTRUCTION(mulxss),
>> +    [CMPEQ]  = INSTRUCTION(cmpeq),
>> +    [0x21]   = INSTRUCTION_ILLEGAL(),
>> +    [0x22]   = INSTRUCTION_ILLEGAL(),
>> +    [0x23]   = INSTRUCTION_ILLEGAL(),
>> +    [DIVU]   = INSTRUCTION(divu),
>> +    [DIV]    = { "div", _div },
>> +    [RDCTL]  = INSTRUCTION(rdctl),
>> +    [MUL]    = INSTRUCTION(mul),
>> +    [CMPGEU] = INSTRUCTION(cmpgeu),
>> +    [INITI]  = INSTRUCTION(initi),
>> +    [0x2a]   = INSTRUCTION_ILLEGAL(),
>> +    [0x2b]   = INSTRUCTION_ILLEGAL(),
>> +    [0x2c]   = INSTRUCTION_ILLEGAL(),
>> +    [TRAP]   = INSTRUCTION(trap),
>> +    [WRCTL]  = INSTRUCTION(wrctl),
>> +    [0x2f]   = INSTRUCTION_ILLEGAL(),
>> +    [CMPLTU] = INSTRUCTION(cmpltu),
>> +    [ADD]    = INSTRUCTION(add),
>> +    [0x32]   = INSTRUCTION_ILLEGAL(),
>> +    [0x33]   = INSTRUCTION_ILLEGAL(),
>> +    [BREAK]  = { "break", __break },
>> +    [0x35]   = INSTRUCTION_ILLEGAL(),
>> +    [SYNC]   = INSTRUCTION(nop),
>> +    [0x37]   = INSTRUCTION_ILLEGAL(),
>> +    [0x38]   = INSTRUCTION_ILLEGAL(),
>> +    [SUB]    = INSTRUCTION(sub),
>> +    [SRAI]   = INSTRUCTION(srai),
>> +    [SRA]    = INSTRUCTION(sra),
>> +    [0x3c]   = INSTRUCTION_ILLEGAL(),
>> +    [0x3d]   = INSTRUCTION_ILLEGAL(),
>> +    [0x3e]   = INSTRUCTION_ILLEGAL(),
>> +    [0x3f]   = INSTRUCTION_ILLEGAL(),
>> +};
> 
> Similar comment wrt the I-type table.
> 
>> +const char *instruction_get_string(uint32_t code)
>> +{
>> +    uint32_t op = get_opcode(code);
>> +
>> +    if (unlikely(op >= I_TYPE_COUNT)) {
>> +        return "";
>> +    } else if (op == R_TYPE) {
>> +        uint32_t opx = get_opxcode(code);
>> +        if (unlikely(opx >= R_TYPE_COUNT)) {
>> +            return "";
>> +        }
>> +        return r_type_instructions[opx].name;
>> +    } else {
>> +        return i_type_instructions[op].name;
>> +    }
>> +}
> 
> What is this function used for?

Nothing, removed.

>> +/* I-Type instruction */
>> +typedef struct Nios2IType {
>> +    uint32_t op:6;
>> +    uint32_t imm16:16;
>> +    uint32_t b:5;
>> +    uint32_t a:5;
>> +} QEMU_PACKED Nios2IType;
> 
> These bitfields are a non-starter.  Layout of them is non-portable in
> more ways than is worth going into here.  You must use extract32 and
> sextract32 to extract the fields.

Fixed

>> +
>> +union i_type_u {
>> +    uint32_t      v;
>> +    Nios2IType i;
>> +};
>> +
>> +#define I_TYPE(instr, op) \
>> +    union i_type_u instr_u = { .v = op }; \
>> +    Nios2IType *instr = &instr_u.i
> 
> You could probably still hide everything behind this macro, with an
> inline function returning a structure (defined *without* bitfields).

Yes, fixed.

>> +/*
>> + * Return values for instruction handlers
>> + */
>> +#define INSTR_UNIMPL     -2  /* Unimplemented instruction */
>> +#define INSTR_ERR        -1  /* Error in instruction */
>> +#define PC_INC_NORMAL     0  /* Normal PC increment after instruction */
>> +#define PC_INC_BY_INSTR   1  /* PC got incremented by instruction */
>> +#define INSTR_BREAK       2  /* Break encountered */
>> +#define INSTR_EXCEPTION 255  /* Instruction generated an exception
>> +                                (the exception cause will be stored
>> +                                in struct nios2 */
> 
> What's the gain over using a simple enum with sequential values?

These are unused, so removed.

>> +/*
>> + * FIXME: Convert to VMstate
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "hw/hw.h"
>> +#include "hw/boards.h"
>> +
>> +void cpu_save(QEMUFile *f, void *opaque)
>> +{
>> +    /* TODO */
>> +}
>> +
>> +int cpu_load(QEMUFile *f, void *opaque, int version_id)
>> +{
>> +    /* TODO */
>> +    return 0;
>> +}
> 
> Fixing this is no longer optional.

This file wasn't even compiled, so removed.

>> +void helper_memalign(CPUNios2State *env, uint32_t addr, uint32_t dr,
>> uint32_t wr, uint32_t mask)
>> +{
>> +    if (addr & mask) {
>> +        qemu_log("unaligned access addr=%x mask=%x, wr=%d dr=r%d\n",
>> +                 addr, mask, wr, dr);
>> +        env->regs[CR_BADADDR] = addr;
>> +        env->regs[CR_EXCEPTION] = EXCP_UNALIGN << 2;
>> +        helper_raise_exception(env, EXCP_UNALIGN);
>> +    }
>> +}
> 
> What is this doing that cc->do_unaligned_access doesn't?

Switched to do_unaligned_access, thanks.

>> +    /* Initialize DC */
>> +    dc->cpu_env = cpu_env;
>> +    dc->cpu_R   = cpu_R;
> 
> What is this assignment for?  Are you planning to implement shadow
> registers at some point?

Eventually yes, but so far I haven't seen that used at all.

> r~

Thanks for the review!

-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [V2,1/7] nios2: Add disas entries
  2016-10-15 13:15 ` [Qemu-devel] [V2,1/7] nios2: Add disas entries Romain Naour
@ 2016-10-18  4:17   ` Marek Vasut
  2016-10-31 21:27     ` Romain Naour
  0 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2016-10-18  4:17 UTC (permalink / raw)
  To: Romain Naour, qemu-devel
  Cc: Jeff Da Silva, Chris Wulff, Sandra Loosemore, Yves Vandervennet,
	Ley Foon Tan, Waldemar Brodkorb

On 10/15/2016 03:15 PM, Romain Naour wrote:
> Hi Marek,

Hi!

> Le 28/09/2016 à 01:30, Marek Vasut a écrit :
>> Add nios2 disassembler support. This patch is composed from binutils files
>> from commit "Opcodes and assembler support for Nios II R2". The files from
>> binutils used in this patch are:
>>
>>     include/opcode/nios2.h
>>     include/opcode/nios2r1.h
>>     include/opcode/nios2r2.h
>>     opcodes/nios2-opc.c
>>     opcodes/nios2-dis.c
> 
> With Waldemar Brodkorb and I, we tested this series using 10m50 kernel defconfig
> with Buildroot generated system. In order to ease the test, we added the device
> tree and a initramfs to the kernel image.
> 
> Here is the result:
> 
> Welcome to Buildroot
> # cat /proc/cpuinfo
> CPU:		Nios II/fast
> MMU:		present
> FPU:		none
> Clocking:	75.00 MHz
> BogoMips:	150.00
> Calibration:	75000000 loops
> HW:
>  MUL:		yes
>  MULX:		no
>  DIV:		yes
> Icache:		32kB, line length: 32
> Dcache:		32kB, line length: 32
> TLB:		16 ways, 256 entries, 8 PID bits
> # uname -a
> Linux buildroot 4.8.1 #2 Fri Oct 14 19:10:18 CEST 2016 nios2 GNU/Linux
> 
> When this series will be accepted in Qemu, I'll add a demo defconfig in
> Buildroot in order to ease runtime testing.
> 
> Tested-by: Romain Naour <romain.naour@gmail.com>

Great, thanks ! I'm glad to see it really becomes usable for other
people too :)

I handled the feedback and pushed updated patches to:
http://git.bfuser.eu/?p=marex/qemu.git;a=shortlog;h=refs/heads/nios2/master

-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support
  2016-10-18  3:58     ` Marek Vasut
@ 2016-10-18 15:31       ` Richard Henderson
  2016-10-18 18:32         ` Marek Vasut
  0 siblings, 1 reply; 21+ messages in thread
From: Richard Henderson @ 2016-10-18 15:31 UTC (permalink / raw)
  To: Marek Vasut, qemu-devel
  Cc: Jeff Da Silva, Chris Wulff, Sandra Loosemore, Yves Vandervennet,
	Ley Foon Tan

On 10/17/2016 08:58 PM, Marek Vasut wrote:
>> There's no particular reason why R_PC needs to be 64; if you change it
>> to 32, you can simplify this.
>
> I believe this is in fact needed, see [1] page 18 (section 2, Register
> file), quote:
>
> "
> The Nios II architecture supports a flat register file, consisting of
> thirty-two 32-bit general-purpose integer
> registers, and up to thirty-two 32-bit control registers. The
> architecture supports supervisor and user
> modes that allow system code to protect the control registers from
> errant applications.
> "
>
> So the CPU supports 32 general purpose regs (R_ZERO..R_RA), then up-to
> 32 Control registers (CR_STATUS..CR_MPUACC) and then the PC .

The architecture manual doesn't imply anything about the numbering of these 
registers.

>> You're not doing anything to make sure that r0 reads as 0, and ignores
>> writes. You need to look at target-alpha, target-mips, or target-sparc
>> to see various ways in which a zero register may be handled.
>
> Any hint on this one ?

Well, there's three hints right there.  But look at target-alpha, and the 
functions load_gpr and dest_gpr (note that for alpha, 31 is the zero register).

>> Since divide-by-zero is undefined, this can be done with
>>
>>   TCGv t0 = tcg_const_tl(0);
>>   tcg_gen_setcond_tl(TCG_COND_EQ, t0, dc->cpu_R[instr->b], t0);
>>   tcg_gen_or_tl(t0, t0, dc->cpu_R[instr->b]);
>>   tcg_gen_divu_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], t0);
>>   tcg_temp_free_tl(t0);
>
> Just so I get it completely, isn't this handled somehow by the
> tcg_gen_divu_tl() itself ?

No, tcg_gen_divu_tl is a plain host divide instruction.

For guests that require exceptions to be raised, we handle those manually 
beforehand.  At which point extra checks in tcg_gen_divu_tl are wasted.



r~

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support
  2016-10-18 15:31       ` Richard Henderson
@ 2016-10-18 18:32         ` Marek Vasut
  2016-10-18 20:44           ` Richard Henderson
  0 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2016-10-18 18:32 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: Jeff Da Silva, Chris Wulff, Sandra Loosemore, Yves Vandervennet,
	Ley Foon Tan

On 10/18/2016 05:31 PM, Richard Henderson wrote:
> On 10/17/2016 08:58 PM, Marek Vasut wrote:
>>> There's no particular reason why R_PC needs to be 64; if you change it
>>> to 32, you can simplify this.
>>
>> I believe this is in fact needed, see [1] page 18 (section 2, Register
>> file), quote:
>>
>> "
>> The Nios II architecture supports a flat register file, consisting of
>> thirty-two 32-bit general-purpose integer
>> registers, and up to thirty-two 32-bit control registers. The
>> architecture supports supervisor and user
>> modes that allow system code to protect the control registers from
>> errant applications.
>> "
>>
>> So the CPU supports 32 general purpose regs (R_ZERO..R_RA), then up-to
>> 32 Control registers (CR_STATUS..CR_MPUACC) and then the PC .
> 
> The architecture manual doesn't imply anything about the numbering of
> these registers.

But the instruction encoding does, so I can use the field from the
instruction to directly index the register array.

>>> You're not doing anything to make sure that r0 reads as 0, and ignores
>>> writes. You need to look at target-alpha, target-mips, or target-sparc
>>> to see various ways in which a zero register may be handled.
>>
>> Any hint on this one ?
> 
> Well, there's three hints right there.  But look at target-alpha, and
> the functions load_gpr and dest_gpr (note that for alpha, 31 is the zero
> register).

Thanks, I hope this is fixed now, although I mostly special-case the
R_ZERO handling throughout the code. Any writes to R_ZERO are now
ignored and any usage is converted to mov/movi instructions where
applicable.

>>> Since divide-by-zero is undefined, this can be done with
>>>
>>>   TCGv t0 = tcg_const_tl(0);
>>>   tcg_gen_setcond_tl(TCG_COND_EQ, t0, dc->cpu_R[instr->b], t0);
>>>   tcg_gen_or_tl(t0, t0, dc->cpu_R[instr->b]);
>>>   tcg_gen_divu_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], t0);
>>>   tcg_temp_free_tl(t0);
>>
>> Just so I get it completely, isn't this handled somehow by the
>> tcg_gen_divu_tl() itself ?
> 
> No, tcg_gen_divu_tl is a plain host divide instruction.
> 
> For guests that require exceptions to be raised, we handle those
> manually beforehand.  At which point extra checks in tcg_gen_divu_tl are
> wasted.

OK, got it, thanks!

-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support
  2016-10-18 18:32         ` Marek Vasut
@ 2016-10-18 20:44           ` Richard Henderson
  2016-10-18 22:05             ` Marek Vasut
  0 siblings, 1 reply; 21+ messages in thread
From: Richard Henderson @ 2016-10-18 20:44 UTC (permalink / raw)
  To: Marek Vasut, qemu-devel
  Cc: Jeff Da Silva, Chris Wulff, Sandra Loosemore, Yves Vandervennet,
	Ley Foon Tan

On 10/18/2016 11:32 AM, Marek Vasut wrote:
> But the instruction encoding does, so I can use the field from the
> instruction to directly index the register array.

Well, no, you can't.

In fact, it would be cleaner to have multiple arrays -- one for general 
registers and one for control registers -- that you *could* actually directly 
index.  There are only two instructions that touch the control registers, rdctl 
and wrctl.  In those instructions you're having to explicitly add 32.

> Thanks, I hope this is fixed now, although I mostly special-case the
> R_ZERO handling throughout the code. Any writes to R_ZERO are now
> ignored and any usage is converted to mov/movi instructions where
> applicable.

We've done that in the past, but in the end it is much cleaner to minimize the 
number of places in which you have to check for R_ZERO.


r~

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support
  2016-10-18 20:44           ` Richard Henderson
@ 2016-10-18 22:05             ` Marek Vasut
  2016-10-19  1:24               ` Richard Henderson
  0 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2016-10-18 22:05 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: Jeff Da Silva, Chris Wulff, Sandra Loosemore, Yves Vandervennet,
	Ley Foon Tan

On 10/18/2016 10:44 PM, Richard Henderson wrote:
> On 10/18/2016 11:32 AM, Marek Vasut wrote:
>> But the instruction encoding does, so I can use the field from the
>> instruction to directly index the register array.
> 
> Well, no, you can't.
> 
> In fact, it would be cleaner to have multiple arrays -- one for general
> registers and one for control registers -- that you *could* actually
> directly index.  There are only two instructions that touch the control
> registers, rdctl and wrctl.  In those instructions you're having to
> explicitly add 32.

Well yes, that's true.

>> Thanks, I hope this is fixed now, although I mostly special-case the
>> R_ZERO handling throughout the code. Any writes to R_ZERO are now
>> ignored and any usage is converted to mov/movi instructions where
>> applicable.
> 
> We've done that in the past, but in the end it is much cleaner to
> minimize the number of places in which you have to check for R_ZERO.

Isn't it a bit more performant if you generate as little TCG
instructions as possible ?

> r~


-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support
  2016-10-18 22:05             ` Marek Vasut
@ 2016-10-19  1:24               ` Richard Henderson
  2016-10-19  2:31                 ` Marek Vasut
  0 siblings, 1 reply; 21+ messages in thread
From: Richard Henderson @ 2016-10-19  1:24 UTC (permalink / raw)
  To: Marek Vasut, qemu-devel
  Cc: Jeff Da Silva, Chris Wulff, Sandra Loosemore, Yves Vandervennet,
	Ley Foon Tan

On 10/18/2016 03:05 PM, Marek Vasut wrote:
>>> Thanks, I hope this is fixed now, although I mostly special-case the
>>> R_ZERO handling throughout the code. Any writes to R_ZERO are now
>>> ignored and any usage is converted to mov/movi instructions where
>>> applicable.
>>
>> We've done that in the past, but in the end it is much cleaner to
>> minimize the number of places in which you have to check for R_ZERO.
>
> Isn't it a bit more performant if you generate as little TCG
> instructions as possible ?

Well, yes and no.

We're always going to run the tcg optimizers, so the resulting code should be 
the same either way.

Processing a little more data can be preferable to fewer branch prediction 
failures.  And the best way to avoid those is to not have the branch at all. 
Especially when it's unlikely that the data will be created in the first place.


r~

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support
  2016-10-19  1:24               ` Richard Henderson
@ 2016-10-19  2:31                 ` Marek Vasut
  2016-10-19 16:18                   ` Richard Henderson
  0 siblings, 1 reply; 21+ messages in thread
From: Marek Vasut @ 2016-10-19  2:31 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: Jeff Da Silva, Chris Wulff, Sandra Loosemore, Yves Vandervennet,
	Ley Foon Tan

On 10/19/2016 03:24 AM, Richard Henderson wrote:
> On 10/18/2016 03:05 PM, Marek Vasut wrote:
>>>> Thanks, I hope this is fixed now, although I mostly special-case the
>>>> R_ZERO handling throughout the code. Any writes to R_ZERO are now
>>>> ignored and any usage is converted to mov/movi instructions where
>>>> applicable.
>>>
>>> We've done that in the past, but in the end it is much cleaner to
>>> minimize the number of places in which you have to check for R_ZERO.
>>
>> Isn't it a bit more performant if you generate as little TCG
>> instructions as possible ?
> 
> Well, yes and no.
> 
> We're always going to run the tcg optimizers, so the resulting code
> should be the same either way.

I see, I'd have to dig deeper into the TCG.

> Processing a little more data can be preferable to fewer branch
> prediction failures.  And the best way to avoid those is to not have the
> branch at all. Especially when it's unlikely that the data will be
> created in the first place.

OK, but I need to make sure stores to ZERO register are ignored, right ?

-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support
  2016-10-19  2:31                 ` Marek Vasut
@ 2016-10-19 16:18                   ` Richard Henderson
  2016-10-20  3:01                     ` Marek Vasut
  0 siblings, 1 reply; 21+ messages in thread
From: Richard Henderson @ 2016-10-19 16:18 UTC (permalink / raw)
  To: Marek Vasut, qemu-devel
  Cc: Jeff Da Silva, Chris Wulff, Sandra Loosemore, Yves Vandervennet,
	Ley Foon Tan

On 10/18/2016 07:31 PM, Marek Vasut wrote:
>> Processing a little more data can be preferable to fewer branch
>> prediction failures.  And the best way to avoid those is to not have the
>> branch at all. Especially when it's unlikely that the data will be
>> created in the first place.
>
> OK, but I need to make sure stores to ZERO register are ignored, right ?

Yes.

Just remember that since nios2 doesn't have condition codes, where side effects 
of an instruction can be useful alone, the *only* likely case of ZERO as a 
destination register is in the (designated) NOP psuedo-op.


r~

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support
  2016-10-19 16:18                   ` Richard Henderson
@ 2016-10-20  3:01                     ` Marek Vasut
  0 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2016-10-20  3:01 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: Jeff Da Silva, Chris Wulff, Sandra Loosemore, Yves Vandervennet,
	Ley Foon Tan

On 10/19/2016 06:18 PM, Richard Henderson wrote:
> On 10/18/2016 07:31 PM, Marek Vasut wrote:
>>> Processing a little more data can be preferable to fewer branch
>>> prediction failures.  And the best way to avoid those is to not have the
>>> branch at all. Especially when it's unlikely that the data will be
>>> created in the first place.
>>
>> OK, but I need to make sure stores to ZERO register are ignored, right ?
> 
> Yes.
> 
> Just remember that since nios2 doesn't have condition codes, where side
> effects of an instruction can be useful alone, the *only* likely case of
> ZERO as a destination register is in the (designated) NOP psuedo-op.

Got it, thanks.

-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [V2,1/7] nios2: Add disas entries
  2016-10-18  4:17   ` Marek Vasut
@ 2016-10-31 21:27     ` Romain Naour
  2016-11-01  0:03       ` Marek Vasut
  0 siblings, 1 reply; 21+ messages in thread
From: Romain Naour @ 2016-10-31 21:27 UTC (permalink / raw)
  To: Marek Vasut, qemu-devel
  Cc: Waldemar Brodkorb, Jeff Da Silva, Chris Wulff, Sandra Loosemore,
	Yves Vandervennet, Ley Foon Tan

Hi Marek, all,

Le 18/10/2016 à 06:17, Marek Vasut a écrit :
> On 10/15/2016 03:15 PM, Romain Naour wrote:
>> Hi Marek,
> 
> Hi!
> 
>> Le 28/09/2016 à 01:30, Marek Vasut a écrit :
>>> Add nios2 disassembler support. This patch is composed from binutils files
>>> from commit "Opcodes and assembler support for Nios II R2". The files from
>>> binutils used in this patch are:
>>>
>>>     include/opcode/nios2.h
>>>     include/opcode/nios2r1.h
>>>     include/opcode/nios2r2.h
>>>     opcodes/nios2-opc.c
>>>     opcodes/nios2-dis.c
>>
>> With Waldemar Brodkorb and I, we tested this series using 10m50 kernel defconfig
>> with Buildroot generated system. In order to ease the test, we added the device
>> tree and a initramfs to the kernel image.
>>
>> Here is the result:
>>
>> Welcome to Buildroot
>> # cat /proc/cpuinfo
>> CPU:		Nios II/fast
>> MMU:		present
>> FPU:		none
>> Clocking:	75.00 MHz
>> BogoMips:	150.00
>> Calibration:	75000000 loops
>> HW:
>>  MUL:		yes
>>  MULX:		no
>>  DIV:		yes
>> Icache:		32kB, line length: 32
>> Dcache:		32kB, line length: 32
>> TLB:		16 ways, 256 entries, 8 PID bits
>> # uname -a
>> Linux buildroot 4.8.1 #2 Fri Oct 14 19:10:18 CEST 2016 nios2 GNU/Linux
>>
>> When this series will be accepted in Qemu, I'll add a demo defconfig in
>> Buildroot in order to ease runtime testing.
>>
>> Tested-by: Romain Naour <romain.naour@gmail.com>
> 
> Great, thanks ! I'm glad to see it really becomes usable for other
> people too :)
> 
> I handled the feedback and pushed updated patches to:
> http://git.bfuser.eu/?p=marex/qemu.git;a=shortlog;h=refs/heads/nios2/master
> 

Thanks, I tried your latest nios2 Qemu (v3 series) + patch 2/3 v6 with a 4.8.5
Linux kernel. It still boot :)

Best regards,
Romain

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [V2,1/7] nios2: Add disas entries
  2016-10-31 21:27     ` Romain Naour
@ 2016-11-01  0:03       ` Marek Vasut
  0 siblings, 0 replies; 21+ messages in thread
From: Marek Vasut @ 2016-11-01  0:03 UTC (permalink / raw)
  To: Romain Naour, qemu-devel
  Cc: Waldemar Brodkorb, Jeff Da Silva, Chris Wulff, Sandra Loosemore,
	Yves Vandervennet, Ley Foon Tan

On 10/31/2016 10:27 PM, Romain Naour wrote:
> Hi Marek, all,

Hi,

> Le 18/10/2016 à 06:17, Marek Vasut a écrit :
>> On 10/15/2016 03:15 PM, Romain Naour wrote:
>>> Hi Marek,
>>
>> Hi!
>>
>>> Le 28/09/2016 à 01:30, Marek Vasut a écrit :
>>>> Add nios2 disassembler support. This patch is composed from binutils files
>>>> from commit "Opcodes and assembler support for Nios II R2". The files from
>>>> binutils used in this patch are:
>>>>
>>>>     include/opcode/nios2.h
>>>>     include/opcode/nios2r1.h
>>>>     include/opcode/nios2r2.h
>>>>     opcodes/nios2-opc.c
>>>>     opcodes/nios2-dis.c
>>>
>>> With Waldemar Brodkorb and I, we tested this series using 10m50 kernel defconfig
>>> with Buildroot generated system. In order to ease the test, we added the device
>>> tree and a initramfs to the kernel image.
>>>
>>> Here is the result:
>>>
>>> Welcome to Buildroot
>>> # cat /proc/cpuinfo
>>> CPU:		Nios II/fast
>>> MMU:		present
>>> FPU:		none
>>> Clocking:	75.00 MHz
>>> BogoMips:	150.00
>>> Calibration:	75000000 loops
>>> HW:
>>>  MUL:		yes
>>>  MULX:		no
>>>  DIV:		yes
>>> Icache:		32kB, line length: 32
>>> Dcache:		32kB, line length: 32
>>> TLB:		16 ways, 256 entries, 8 PID bits
>>> # uname -a
>>> Linux buildroot 4.8.1 #2 Fri Oct 14 19:10:18 CEST 2016 nios2 GNU/Linux
>>>
>>> When this series will be accepted in Qemu, I'll add a demo defconfig in
>>> Buildroot in order to ease runtime testing.
>>>
>>> Tested-by: Romain Naour <romain.naour@gmail.com>
>>
>> Great, thanks ! I'm glad to see it really becomes usable for other
>> people too :)
>>
>> I handled the feedback and pushed updated patches to:
>> http://git.bfuser.eu/?p=marex/qemu.git;a=shortlog;h=refs/heads/nios2/master
>>
> 
> Thanks, I tried your latest nios2 Qemu (v3 series) + patch 2/3 v6 with a 4.8.5
> Linux kernel. It still boot :)

Great, thanks for checking :)

-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2016-11-01  2:25 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-27 23:30 [Qemu-devel] [PATCH V2 1/7] nios2: Add disas entries Marek Vasut
2016-09-27 23:30 ` [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support Marek Vasut
2016-09-29  1:05   ` Richard Henderson
2016-10-18  3:58     ` Marek Vasut
2016-10-18 15:31       ` Richard Henderson
2016-10-18 18:32         ` Marek Vasut
2016-10-18 20:44           ` Richard Henderson
2016-10-18 22:05             ` Marek Vasut
2016-10-19  1:24               ` Richard Henderson
2016-10-19  2:31                 ` Marek Vasut
2016-10-19 16:18                   ` Richard Henderson
2016-10-20  3:01                     ` Marek Vasut
2016-09-27 23:30 ` [Qemu-devel] [PATCH 3/7] nios2: Add usermode binaries emulation Marek Vasut
2016-09-27 23:30 ` [Qemu-devel] [PATCH 4/7] nios2: Add IIC interrupt controller emulation Marek Vasut
2016-09-27 23:30 ` [Qemu-devel] [PATCH 5/7] nios2: Add periodic timer emulation Marek Vasut
2016-09-27 23:30 ` [Qemu-devel] [PATCH 6/7] nios2: Add Altera 10M50 GHRD emulation Marek Vasut
2016-09-27 23:30 ` [Qemu-devel] [PATCH 7/7] nios2: Add support for Nios-II R1 Marek Vasut
2016-10-15 13:15 ` [Qemu-devel] [V2,1/7] nios2: Add disas entries Romain Naour
2016-10-18  4:17   ` Marek Vasut
2016-10-31 21:27     ` Romain Naour
2016-11-01  0:03       ` Marek Vasut

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.