qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support
@ 2012-06-21  2:57 Jia Liu
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 01/16] target-or32: Add target stubs and cpu support Jia Liu
                   ` (15 more replies)
  0 siblings, 16 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:57 UTC (permalink / raw)
  To: qemu-devel

This is the OpenCores OpenRISC 1200 support for QEMU.
Full implementation of the system-model and linux-user-model support.

OpenRISC 1200 is a OpenCores open source CPU,
its architecture manual can be found at
http://opencores.org/svnget,or1k?file=/trunk/docs/openrisc_arch.pdf

A OpenRISC Linux kernel contain initramfs for qemu-system-or32 testing
can be found at
https://docs.google.com/file/d/0BxeTrz3x0CBLSjR3Sk5Vd3h1eDA/edit?pli=1

A OpenRISC hello-world program for qemu-or32 testing can be found at
https://docs.google.com/file/d/0BxeTrz3x0CBLN3RSWUFNYktrU2M/edit?pli=1

Signed-off-by: Jia Liu <proljc@gmail.com>
---

Version History:
V6:
Addressed Blue's review comments:
- reimplement l.mul* l.mfspr.
- fix l.mtspr l.sub.
- some English typo fix.
- some coding style fix.

Addressed Max's review comments:
- replace NE2000 with OpenCores 10/100 ethernet adapter, thanks for his patch.

V5:
Addressed Blue's review comments:
- reimplement l.mul* l.mtspr l.add* l.sub* and more.
- shoot bugs with "--enable-debug-tcg".

V4:
Addressed Max's review comments:
- fix l.div l.mac* l.mul*, and more.

Addressed Richard, Wei-Ren and Andreas's review comments:
- replace tcg_temp_new_i32 with tcg_temp_local_new_i32 in l.div translation.

Addressed Andreas's review comments:
- update to suit Makefile system.

- add UPR CPUCFGR and MMUCFGR impelement.
- add instruction check functions.

Version History:
V3:
Addressed Stefan and Andreas's review comments:
- use QEMU and OpenRISC's official name.

Addressed Andreas's review comments:
- reimplement cpu QOM.
- combine target stubs and QOM implement.
- use new commit message and subject.

Addressed Max's review comments:
- handle div zero exception.
- reimplement float point instructions.
- fix l.mac*, l.mul*, and more.

V2:
Addressed Malc, Weiren, Andreas and Blue's review comments:
- reimplement cpu QOM.

Addressed Andreas's review comments:
- reimplement machine.
- rewrite the Copyright Notice using better format.

Addressed Blue and Weiren's review comments:
- compiling with AREG0 and remove global env, no dyngen-exe longer.

Addressed Max, Blue and Weiren's review comments:
- handle div zero exception.
- handle illegal instruction.

Addressed Blue's review comments:
- separate do_interrupt into intrpt.c form intrpt_helper.c.
- add QEMU_NORETURN to raise_exception.
- reimplement float instrutions.
- fix type of linux syscall and termbits.
- reimplement sim board.
- use the LGPL web URL in Copyright Notice.
- reimplemt branch instructions.

- split taregt stubs, QOM and machine.

V1:
- add QEMU OpenRISC support.
- well tested on x64 machine, and final tested x86 machine.

Jia Liu (16):
  target-or32: Add target stubs and cpu support
  target-or32: Add target machine
  target-or32: Add MMU support
  target-or32: Add interrupt support
  target-or32: Add exception support
  target-or32: Add int instruction helpers
  target-or32: Add float instruction helpers
  target-or32: Add instruction tanslation
  target-or32: Add PIC support
  target-or32: Add timer support
  target-or32: Add a IIS dummy board
  target-or32: Add system instructions
  target-or32: Add gdb stub
  target-or32: Add linux syscall, signal and termbits
  target-or32: Add linux user support
  target-or32: Add testcases

 arch_init.c                         |    2 +
 arch_init.h                         |    1 +
 configure                           |   15 +-
 cpu-exec.c                          |   19 +
 default-configs/or32-linux-user.mak |    1 +
 default-configs/or32-softmmu.mak    |    4 +
 elf.h                               |    2 +
 gdbstub.c                           |   64 ++
 hw/openrisc/Makefile.objs           |    3 +
 hw/openrisc_cpudev.h                |   29 +
 hw/openrisc_pic.c                   |   78 ++
 hw/openrisc_sim.c                   |  160 ++++
 hw/openrisc_timer.c                 |  160 ++++
 linux-user/elfload.c                |   41 +
 linux-user/main.c                   |  100 ++
 linux-user/openrisc/syscall.h       |   24 +
 linux-user/openrisc/syscall_nr.h    |  506 ++++++++++
 linux-user/openrisc/target_signal.h |   26 +
 linux-user/openrisc/termbits.h      |  294 ++++++
 linux-user/signal.c                 |  229 +++++
 linux-user/syscall.c                |    2 +-
 linux-user/syscall_defs.h           |   40 +-
 poison.h                            |    1 +
 target-openrisc/Makefile.objs       |    4 +
 target-openrisc/cpu.c               |  240 +++++
 target-openrisc/cpu.h               |  449 +++++++++
 target-openrisc/excp.c              |   27 +
 target-openrisc/excp.h              |   28 +
 target-openrisc/excp_helper.c       |   27 +
 target-openrisc/fpu_helper.c        |  275 ++++++
 target-openrisc/helper.h            |   70 ++
 target-openrisc/int_helper.c        |   85 ++
 target-openrisc/intrpt.c            |   74 ++
 target-openrisc/intrpt_helper.c     |   52 ++
 target-openrisc/machine.c           |   50 +
 target-openrisc/mmu.c               |  236 +++++
 target-openrisc/mmu_helper.c        |   63 ++
 target-openrisc/sys_helper.c        |  244 +++++
 target-openrisc/translate.c         | 1761 +++++++++++++++++++++++++++++++++++
 tests/tcg/openrisc/Makefile         |   71 ++
 tests/tcg/openrisc/test_add.c       |   34 +
 tests/tcg/openrisc/test_addc.c      |   39 +
 tests/tcg/openrisc/test_addi.c      |   31 +
 tests/tcg/openrisc/test_addic.c     |   33 +
 tests/tcg/openrisc/test_and_or.c    |   61 ++
 tests/tcg/openrisc/test_bf.c        |   46 +
 tests/tcg/openrisc/test_bnf.c       |   50 +
 tests/tcg/openrisc/test_div.c       |   32 +
 tests/tcg/openrisc/test_divu.c      |   32 +
 tests/tcg/openrisc/test_extx.c      |   72 ++
 tests/tcg/openrisc/test_fx.c        |   53 ++
 tests/tcg/openrisc/test_j.c         |   26 +
 tests/tcg/openrisc/test_jal.c       |   26 +
 tests/tcg/openrisc/test_lf_add.c    |   39 +
 tests/tcg/openrisc/test_lf_div.c    |   34 +
 tests/tcg/openrisc/test_lf_eqs.c    |   84 ++
 tests/tcg/openrisc/test_lf_ges.c    |   84 ++
 tests/tcg/openrisc/test_lf_gts.c    |   84 ++
 tests/tcg/openrisc/test_lf_les.c    |   84 ++
 tests/tcg/openrisc/test_lf_lts.c    |   91 ++
 tests/tcg/openrisc/test_lf_mul.c    |   22 +
 tests/tcg/openrisc/test_lf_nes.c    |   87 ++
 tests/tcg/openrisc/test_lf_rem.c    |   32 +
 tests/tcg/openrisc/test_lf_sub.c    |   33 +
 tests/tcg/openrisc/test_logic.c     |  100 ++
 tests/tcg/openrisc/test_lx.c        |   78 ++
 tests/tcg/openrisc/test_movhi.c     |   30 +
 tests/tcg/openrisc/test_mul.c       |   47 +
 tests/tcg/openrisc/test_muli.c      |   47 +
 tests/tcg/openrisc/test_mulu.c      |   47 +
 tests/tcg/openrisc/test_sfeq.c      |   44 +
 tests/tcg/openrisc/test_sfeqi.c     |   39 +
 tests/tcg/openrisc/test_sfges.c     |   44 +
 tests/tcg/openrisc/test_sfgesi.c    |   40 +
 tests/tcg/openrisc/test_sfgeu.c     |   44 +
 tests/tcg/openrisc/test_sfgeui.c    |   41 +
 tests/tcg/openrisc/test_sfgts.c     |   45 +
 tests/tcg/openrisc/test_sfgtsi.c    |   41 +
 tests/tcg/openrisc/test_sfgtu.c     |   43 +
 tests/tcg/openrisc/test_sfgtui.c    |   42 +
 tests/tcg/openrisc/test_sfles.c     |   26 +
 tests/tcg/openrisc/test_sflesi.c    |   39 +
 tests/tcg/openrisc/test_sfleu.c     |   43 +
 tests/tcg/openrisc/test_sfleui.c    |   39 +
 tests/tcg/openrisc/test_sflts.c     |   43 +
 tests/tcg/openrisc/test_sfltsi.c    |   38 +
 tests/tcg/openrisc/test_sfltu.c     |   41 +
 tests/tcg/openrisc/test_sfltui.c    |   39 +
 tests/tcg/openrisc/test_sfne.c      |   43 +
 tests/tcg/openrisc/test_sfnei.c     |   38 +
 tests/tcg/openrisc/test_sub.c       |   34 +
 91 files changed, 7955 insertions(+), 6 deletions(-)
 create mode 100644 default-configs/or32-linux-user.mak
 create mode 100644 default-configs/or32-softmmu.mak
 create mode 100644 hw/openrisc/Makefile.objs
 create mode 100644 hw/openrisc_cpudev.h
 create mode 100644 hw/openrisc_pic.c
 create mode 100644 hw/openrisc_sim.c
 create mode 100644 hw/openrisc_timer.c
 create mode 100644 linux-user/openrisc/syscall.h
 create mode 100644 linux-user/openrisc/syscall_nr.h
 create mode 100644 linux-user/openrisc/target_signal.h
 create mode 100644 linux-user/openrisc/termbits.h
 create mode 100644 target-openrisc/Makefile.objs
 create mode 100644 target-openrisc/cpu.c
 create mode 100644 target-openrisc/cpu.h
 create mode 100644 target-openrisc/excp.c
 create mode 100644 target-openrisc/excp.h
 create mode 100644 target-openrisc/excp_helper.c
 create mode 100644 target-openrisc/fpu_helper.c
 create mode 100644 target-openrisc/helper.h
 create mode 100644 target-openrisc/int_helper.c
 create mode 100644 target-openrisc/intrpt.c
 create mode 100644 target-openrisc/intrpt_helper.c
 create mode 100644 target-openrisc/machine.c
 create mode 100644 target-openrisc/mmu.c
 create mode 100644 target-openrisc/mmu_helper.c
 create mode 100644 target-openrisc/sys_helper.c
 create mode 100644 target-openrisc/translate.c
 create mode 100644 tests/tcg/openrisc/Makefile
 create mode 100644 tests/tcg/openrisc/test_add.c
 create mode 100644 tests/tcg/openrisc/test_addc.c
 create mode 100644 tests/tcg/openrisc/test_addi.c
 create mode 100644 tests/tcg/openrisc/test_addic.c
 create mode 100644 tests/tcg/openrisc/test_and_or.c
 create mode 100644 tests/tcg/openrisc/test_bf.c
 create mode 100644 tests/tcg/openrisc/test_bnf.c
 create mode 100644 tests/tcg/openrisc/test_div.c
 create mode 100644 tests/tcg/openrisc/test_divu.c
 create mode 100644 tests/tcg/openrisc/test_extx.c
 create mode 100644 tests/tcg/openrisc/test_fx.c
 create mode 100644 tests/tcg/openrisc/test_j.c
 create mode 100644 tests/tcg/openrisc/test_jal.c
 create mode 100644 tests/tcg/openrisc/test_lf_add.c
 create mode 100644 tests/tcg/openrisc/test_lf_div.c
 create mode 100644 tests/tcg/openrisc/test_lf_eqs.c
 create mode 100644 tests/tcg/openrisc/test_lf_ges.c
 create mode 100644 tests/tcg/openrisc/test_lf_gts.c
 create mode 100644 tests/tcg/openrisc/test_lf_les.c
 create mode 100644 tests/tcg/openrisc/test_lf_lts.c
 create mode 100644 tests/tcg/openrisc/test_lf_mul.c
 create mode 100644 tests/tcg/openrisc/test_lf_nes.c
 create mode 100644 tests/tcg/openrisc/test_lf_rem.c
 create mode 100644 tests/tcg/openrisc/test_lf_sub.c
 create mode 100644 tests/tcg/openrisc/test_logic.c
 create mode 100644 tests/tcg/openrisc/test_lx.c
 create mode 100644 tests/tcg/openrisc/test_movhi.c
 create mode 100644 tests/tcg/openrisc/test_mul.c
 create mode 100644 tests/tcg/openrisc/test_muli.c
 create mode 100644 tests/tcg/openrisc/test_mulu.c
 create mode 100644 tests/tcg/openrisc/test_sfeq.c
 create mode 100644 tests/tcg/openrisc/test_sfeqi.c
 create mode 100644 tests/tcg/openrisc/test_sfges.c
 create mode 100644 tests/tcg/openrisc/test_sfgesi.c
 create mode 100644 tests/tcg/openrisc/test_sfgeu.c
 create mode 100644 tests/tcg/openrisc/test_sfgeui.c
 create mode 100644 tests/tcg/openrisc/test_sfgts.c
 create mode 100644 tests/tcg/openrisc/test_sfgtsi.c
 create mode 100644 tests/tcg/openrisc/test_sfgtu.c
 create mode 100644 tests/tcg/openrisc/test_sfgtui.c
 create mode 100644 tests/tcg/openrisc/test_sfles.c
 create mode 100644 tests/tcg/openrisc/test_sflesi.c
 create mode 100644 tests/tcg/openrisc/test_sfleu.c
 create mode 100644 tests/tcg/openrisc/test_sfleui.c
 create mode 100644 tests/tcg/openrisc/test_sflts.c
 create mode 100644 tests/tcg/openrisc/test_sfltsi.c
 create mode 100644 tests/tcg/openrisc/test_sfltu.c
 create mode 100644 tests/tcg/openrisc/test_sfltui.c
 create mode 100644 tests/tcg/openrisc/test_sfne.c
 create mode 100644 tests/tcg/openrisc/test_sfnei.c
 create mode 100644 tests/tcg/openrisc/test_sub.c

-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 01/16] target-or32: Add target stubs and cpu support
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
@ 2012-06-21  2:57 ` Jia Liu
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 02/16] target-or32: Add target machine Jia Liu
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:57 UTC (permalink / raw)
  To: qemu-devel

Add OpenRISC target stubs and cpu support.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 arch_init.c                      |    2 +
 arch_init.h                      |    1 +
 configure                        |   14 +-
 cpu-exec.c                       |    2 +
 default-configs/or32-softmmu.mak |    4 +
 elf.h                            |    2 +
 hw/openrisc/Makefile.objs        |    3 +
 hw/openrisc_cpudev.h             |   29 ++++
 hw/openrisc_pic.c                |   30 ++++
 hw/openrisc_timer.c              |   30 ++++
 poison.h                         |    1 +
 target-openrisc/Makefile.objs    |    3 +
 target-openrisc/cpu.c            |  240 +++++++++++++++++++++++++++++++
 target-openrisc/cpu.h            |  292 ++++++++++++++++++++++++++++++++++++++
 target-openrisc/intrpt.c         |   30 ++++
 target-openrisc/machine.c        |   30 ++++
 target-openrisc/mmu.c            |   39 +++++
 target-openrisc/mmu_helper.c     |   43 ++++++
 target-openrisc/translate.c      |   75 ++++++++++
 19 files changed, 868 insertions(+), 2 deletions(-)
 create mode 100644 default-configs/or32-softmmu.mak
 create mode 100644 hw/openrisc/Makefile.objs
 create mode 100644 hw/openrisc_cpudev.h
 create mode 100644 hw/openrisc_pic.c
 create mode 100644 hw/openrisc_timer.c
 create mode 100644 target-openrisc/Makefile.objs
 create mode 100644 target-openrisc/cpu.c
 create mode 100644 target-openrisc/cpu.h
 create mode 100644 target-openrisc/intrpt.c
 create mode 100644 target-openrisc/machine.c
 create mode 100644 target-openrisc/mmu.c
 create mode 100644 target-openrisc/mmu_helper.c
 create mode 100644 target-openrisc/translate.c

diff --git a/arch_init.c b/arch_init.c
index a9e8b74..4b521e5 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -71,6 +71,8 @@ int graphic_depth = 15;
 #define QEMU_ARCH QEMU_ARCH_MICROBLAZE
 #elif defined(TARGET_MIPS)
 #define QEMU_ARCH QEMU_ARCH_MIPS
+#elif defined(TARGET_OPENRISC)
+#define QEMU_ARCH QEMU_ARCH_OPENRISC
 #elif defined(TARGET_PPC)
 #define QEMU_ARCH QEMU_ARCH_PPC
 #elif defined(TARGET_S390X)
diff --git a/arch_init.h b/arch_init.h
index c7cb94a..3dfea3b 100644
--- a/arch_init.h
+++ b/arch_init.h
@@ -16,6 +16,7 @@ enum {
     QEMU_ARCH_SH4 = 1024,
     QEMU_ARCH_SPARC = 2048,
     QEMU_ARCH_XTENSA = 4096,
+    QEMU_ARCH_OPENRISC = 8192,
 };
 
 extern const uint32_t arch_type;
diff --git a/configure b/configure
index b68c0ca..80ee0be 100755
--- a/configure
+++ b/configure
@@ -924,6 +924,7 @@ mips-softmmu \
 mipsel-softmmu \
 mips64-softmmu \
 mips64el-softmmu \
+or32-softmmu \
 ppc-softmmu \
 ppcemb-softmmu \
 ppc64-softmmu \
@@ -3485,7 +3486,7 @@ target_arch2=`echo $target | cut -d '-' -f 1`
 target_bigendian="no"
 
 case "$target_arch2" in
-  armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
+  armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|or32|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
   target_bigendian=yes
   ;;
 esac
@@ -3601,6 +3602,11 @@ case "$target_arch2" in
     target_phys_bits=64
     target_long_alignment=8
   ;;
+  or32)
+    TARGET_ARCH=openrisc
+    TARGET_BASE_ARCH=openrisc
+    target_phys_bits=32
+  ;;
   ppc)
     gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
     target_phys_bits=64
@@ -3679,7 +3685,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
 
 
 case "$target_arch2" in
-  alpha | sparc* | xtensa*)
+  alpha | or32 | sparc* | xtensa*)
     echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
   ;;
 esac
@@ -3850,6 +3856,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
     echo "CONFIG_MIPS_DIS=y"  >> $config_target_mak
     echo "CONFIG_MIPS_DIS=y"  >> $libdis_config_mak
   ;;
+  or32)
+    echo "CONFIG_OPENRISC_DIS=y"  >> $config_target_mak
+    echo "CONFIG_OPENRISC_DIS=y"  >> $libdis_config_mak
+  ;;
   ppc*)
     echo "CONFIG_PPC_DIS=y"  >> $config_target_mak
     echo "CONFIG_PPC_DIS=y"  >> $libdis_config_mak
diff --git a/cpu-exec.c b/cpu-exec.c
index 624c409..7d0d87b 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -225,6 +225,7 @@ int cpu_exec(CPUArchState *env)
 #elif defined(TARGET_LM32)
 #elif defined(TARGET_MICROBLAZE)
 #elif defined(TARGET_MIPS)
+#elif defined(TARGET_OPENRISC)
 #elif defined(TARGET_SH4)
 #elif defined(TARGET_CRIS)
 #elif defined(TARGET_S390X)
@@ -630,6 +631,7 @@ int cpu_exec(CPUArchState *env)
               | env->cc_dest | (env->cc_x << 4);
 #elif defined(TARGET_MICROBLAZE)
 #elif defined(TARGET_MIPS)
+#elif defined(TARGET_OPENRISC)
 #elif defined(TARGET_SH4)
 #elif defined(TARGET_ALPHA)
 #elif defined(TARGET_CRIS)
diff --git a/default-configs/or32-softmmu.mak b/default-configs/or32-softmmu.mak
new file mode 100644
index 0000000..cce4746
--- /dev/null
+++ b/default-configs/or32-softmmu.mak
@@ -0,0 +1,4 @@
+# Default configuration for or32-softmmu
+
+CONFIG_SERIAL=y
+CONFIG_OPENCORES_ETH=y
diff --git a/elf.h b/elf.h
index 9c9acfa..a21ea53 100644
--- a/elf.h
+++ b/elf.h
@@ -106,6 +106,8 @@ typedef int64_t  Elf64_Sxword;
 #define EM_H8S          48      /* Hitachi H8S     */
 #define EM_LATTICEMICO32 138    /* LatticeMico32 */
 
+#define EM_OPENRISC     92        /* OpenCores OpenRISC */
+
 #define EM_UNICORE32    110     /* UniCore32 */
 
 /*
diff --git a/hw/openrisc/Makefile.objs b/hw/openrisc/Makefile.objs
new file mode 100644
index 0000000..1c541a5
--- /dev/null
+++ b/hw/openrisc/Makefile.objs
@@ -0,0 +1,3 @@
+obj-y = openrisc_pic.o openrisc_timer.o
+
+obj-y := $(addprefix ../,$(obj-y))
diff --git a/hw/openrisc_cpudev.h b/hw/openrisc_cpudev.h
new file mode 100644
index 0000000..01bd422
--- /dev/null
+++ b/hw/openrisc_cpudev.h
@@ -0,0 +1,29 @@
+/*
+ *  QEMU OpenRISC CPU device support.
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@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 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 HW_OPENRISC_CPUDEV_H
+#define HW_OPENRISC_CPUDEV_H
+
+/* openrisc_pic.c */
+void cpu_openrisc_pic_init(CPUOpenRISCState *env);
+
+/* openrisc_timer.c*/
+void cpu_openrisc_clock_init(CPUOpenRISCState *env);
+
+#endif
diff --git a/hw/openrisc_pic.c b/hw/openrisc_pic.c
new file mode 100644
index 0000000..0d14bbe
--- /dev/null
+++ b/hw/openrisc_pic.c
@@ -0,0 +1,30 @@
+/*
+ *  OpenRISC Programmable Interrupt Controller support.
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
+ *                          Feng Gao <gf91597@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 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/>.
+ */
+
+#include "hw.h"
+#include "openrisc_cpudev.h"
+#include "cpu.h"
+
+/* Reset PIC */
+void cpu_openrisc_pic_reset(CPUOpenRISCState *env)
+{
+    env->picmr = 0x00000000;
+    env->picsr = 0x00000000;
+}
diff --git a/hw/openrisc_timer.c b/hw/openrisc_timer.c
new file mode 100644
index 0000000..df384f6
--- /dev/null
+++ b/hw/openrisc_timer.c
@@ -0,0 +1,30 @@
+/*
+ *  QEMU OpenRISC timer support
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
+ *                          Zhizhou Zhang <etouzh@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 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/>.
+ */
+
+#include "hw.h"
+#include "openrisc_cpudev.h"
+#include "qemu-timer.h"
+
+/* Reset Timer */
+void cpu_openrisc_timer_reset(CPUOpenRISCState *env)
+{
+    env->ttmr = 0x00000000;
+    env->ttcr = 0x00000000;
+}
diff --git a/poison.h b/poison.h
index d396f20..7d7b23b 100644
--- a/poison.h
+++ b/poison.h
@@ -14,6 +14,7 @@
 #pragma GCC poison TARGET_M68K
 #pragma GCC poison TARGET_MIPS
 #pragma GCC poison TARGET_MIPS64
+#pragma GCC poison TARGET_OPENRISC
 #pragma GCC poison TARGET_PPC
 #pragma GCC poison TARGET_PPCEMB
 #pragma GCC poison TARGET_PPC64
diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs
new file mode 100644
index 0000000..21b76b2
--- /dev/null
+++ b/target-openrisc/Makefile.objs
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SOFTMMU) += machine.o
+obj-y += cpu.o intrpt.o mmu.o translate.o
+obj-y += mmu_helper.o
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
new file mode 100644
index 0000000..a99910c
--- /dev/null
+++ b/target-openrisc/cpu.c
@@ -0,0 +1,240 @@
+/*
+ *  QEMU OpenRISC CPU
+ *
+ *  Copyright (c) 2012 Jia Liu <proljc@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 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/>.
+ */
+
+#include "cpu.h"
+#include "qemu-common.h"
+#ifndef CONFIG_USER_ONLY
+#include "hw/loader.h"
+#endif
+
+/* CPUClass::reset() */
+static void openrisc_cpu_reset(CPUState *s)
+{
+    OpenRISCCPU *cpu = OPENRISC_CPU(s);
+    OpenRISCCPUClass *occ = OPENRISC_CPU_GET_CLASS(cpu);
+    CPUOpenRISCState *env = &cpu->env;
+
+    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        log_cpu_state(env, 0);
+    }
+
+    occ->parent_reset(s);
+
+    memset(env, 0, offsetof(CPUOpenRISCState, breakpoints));
+
+    tlb_flush(env, 1);
+    /*tb_flush(env);    FIXME: Do we need it?  */
+
+    env->pc = 0x100;
+    env->sr = SR_FO | SR_SM;
+    env->exception_index = -1;
+
+    env->upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP;
+    env->cpucfgr = CPUCFGR_OB32S | CPUCFGR_OF32S;
+    env->dmmucfgr = (DMMUCFGR_NTW & (0 << 2)) | (DMMUCFGR_NTS & (6 << 2));
+    env->immucfgr = (IMMUCFGR_NTW & (0 << 2)) | (IMMUCFGR_NTS & (6 << 2));
+
+#ifndef CONFIG_USER_ONLY
+    cpu_openrisc_timer_reset(env);
+    cpu_openrisc_pic_reset(env);
+#endif
+}
+
+static inline int openrisc_feature(CPUOpenRISCState *env, int feature)
+{
+    return (env->feature & (1u << feature)) != 0;
+}
+
+static inline void set_feature(CPUOpenRISCState *env, int feature)
+{
+    env->feature |= 1u << feature;
+}
+
+void openrisc_cpu_realize(Object *obj, Error **errp)
+{
+    OpenRISCCPU *cpu = OPENRISC_CPU(obj);
+    CPUOpenRISCState *env = &cpu->env;
+    if (openrisc_feature(env, OPENRISC_FEATURE_OR1200)) {
+        set_feature(env, OPENRISC_FEATURE_OB32S);
+        set_feature(env, OPENRISC_FEATURE_OF32S);
+    }
+
+    qemu_init_vcpu(&cpu->env);
+}
+
+static void openrisc_cpu_initfn(Object *obj)
+{
+    OpenRISCCPU *cpu = OPENRISC_CPU(obj);
+    cpu_exec_init(&cpu->env);
+}
+
+/* CPU models */
+static void or1200_initfn(Object *obj)
+{
+    OpenRISCCPU *cpu = OPENRISC_CPU(obj);
+    CPUOpenRISCState *env = &cpu->env;
+
+    set_feature(env, OPENRISC_FEATURE_OR1200);
+
+    cpu_reset(CPU(cpu));
+
+}
+
+static void openrisc_any_initfn(Object *obj)
+{
+    OpenRISCCPU *cpu = OPENRISC_CPU(obj);
+    CPUOpenRISCState *env = &cpu->env;
+
+    set_feature(env, OPENRISC_FEATURE_OB32S);
+    set_feature(env, OPENRISC_FEATURE_OF32S);
+
+    cpu_reset(CPU(cpu));
+}
+
+typedef struct OpenRISCCPUInfo {
+    const char *name;
+    void (*initfn)(Object *obj);
+} OpenRISCCPUInfo;
+
+static const OpenRISCCPUInfo openrisc_cpus[] = {
+    { .name = "or1200",      .initfn = or1200_initfn },
+    { .name = "any",         .initfn = openrisc_any_initfn },
+};
+
+static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
+{
+    OpenRISCCPUClass *occ = OPENRISC_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(occ);
+
+    occ->parent_reset = cc->reset;
+    cc->reset = openrisc_cpu_reset;
+}
+
+static void cpu_register(const OpenRISCCPUInfo *info)
+{
+    TypeInfo type_info = {
+        .name = info->name,
+        .parent = TYPE_OPENRISC_CPU,
+        .instance_size = sizeof(OpenRISCCPU),
+        .instance_init = info->initfn,
+        .class_size = sizeof(OpenRISCCPUClass),
+    };
+
+    type_register_static(&type_info);
+}
+
+static const TypeInfo openrisc_cpu_type_info = {
+    .name = TYPE_OPENRISC_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(OpenRISCCPU),
+    .instance_init = openrisc_cpu_initfn,
+    .abstract = false,
+    .class_size = sizeof(OpenRISCCPUClass),
+    .class_init = openrisc_cpu_class_init,
+};
+
+static void openrisc_cpu_register_types(void)
+{
+    int i;
+
+    type_register_static(&openrisc_cpu_type_info);
+    for (i = 0; i < ARRAY_SIZE(openrisc_cpus); i++) {
+        cpu_register(&openrisc_cpus[i]);
+    }
+}
+
+OpenRISCCPU *cpu_openrisc_init(const char *cpu_model)
+{
+    OpenRISCCPU *cpu;
+    CPUOpenRISCState *env;
+    static int inited;
+    inited = 0;
+
+    if (!object_class_by_name(cpu_model)) {
+        return NULL;
+    }
+    cpu = OPENRISC_CPU(object_new(cpu_model));
+    env = &cpu->env;
+    env->cpu_model_str = cpu_model;
+
+    openrisc_cpu_realize(OBJECT(cpu), NULL);
+
+#ifndef CONFIG_USER_ONLY
+    openrisc_mmu_init(env);
+#endif
+
+    if (tcg_enabled() && !inited) {
+        inited = 1;
+        openrisc_translate_init();
+    }
+
+    cpu_reset(CPU(cpu));
+
+    return cpu;
+}
+
+typedef struct OpenRISCCPUListState {
+    fprintf_function cpu_fprintf;
+    FILE *file;
+} OpenRISCCPUListState;
+
+/* Sort alphabetically by type name, except for "any". */
+static gint openrisc_cpu_list_compare(gconstpointer a, gconstpointer b)
+{
+    ObjectClass *class_a = (ObjectClass *)a;
+    ObjectClass *class_b = (ObjectClass *)b;
+    const char *name_a, *name_b;
+
+    name_a = object_class_get_name(class_a);
+    name_b = object_class_get_name(class_b);
+    if (strcmp(name_a, "any") == 0) {
+        return 1;
+    } else if (strcmp(name_b, "any") == 0) {
+        return -1;
+    } else {
+        return strcmp(name_a, name_b);
+    }
+}
+
+static void openrisc_cpu_list_entry(gpointer data, gpointer user_data)
+{
+    ObjectClass *oc = data;
+    OpenRISCCPUListState *s = user_data;
+
+    (*s->cpu_fprintf)(s->file, "  %s\n",
+                      object_class_get_name(oc));
+}
+
+void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf)
+{
+    OpenRISCCPUListState s = {
+        .file = f,
+        .cpu_fprintf = cpu_fprintf,
+    };
+    GSList *list;
+
+    list = object_class_get_list(TYPE_OPENRISC_CPU, false);
+    list = g_slist_sort(list, openrisc_cpu_list_compare);
+    (*cpu_fprintf)(f, "Available CPUs:\n");
+    g_slist_foreach(list, openrisc_cpu_list_entry, &s);
+    g_slist_free(list);
+}
+
+type_init(openrisc_cpu_register_types)
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
new file mode 100644
index 0000000..0b8e836
--- /dev/null
+++ b/target-openrisc/cpu.h
@@ -0,0 +1,292 @@
+/*
+ *  OpenRISC virtual CPU header.
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@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 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 CPU_OPENRISC_H
+#define CPU_OPENRISC_H
+
+#define TARGET_HAS_ICE 1
+
+#define CPUArchState struct CPUOpenRISCState
+
+#if defined(TARGET_OPENRISC64)
+#define TARGET_LONG_BITS 64
+#define ELF_MACHINE    EM_NONE
+#else
+#define TARGET_LONG_BITS 32
+#define ELF_MACHINE    EM_OPENRISC
+#endif
+
+#include "config.h"
+#include "qemu-common.h"
+#include "cpu-defs.h"
+#include "softfloat.h"
+#include "qemu/cpu.h"
+#include "error.h"
+
+struct CPUOpenRISCState;
+
+#define NB_MMU_MODES    3
+
+#define TARGET_PAGE_BITS 13
+
+#define TARGET_PHYS_ADDR_SPACE_BITS 32
+#define TARGET_VIRT_ADDR_SPACE_BITS 32
+
+/* Internal flags, delay slot flag */
+#define D_FLAG    1
+
+/* Verison Register */
+#define SPR_VR       0xFFFF003F
+
+/* Registers */
+enum {
+    R0 = 0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10,
+    R11, R12, R13, R14, R15, R16, R17, R18, R19, R20,
+    R21, R22, R23, R24, R25, R26, R27, R28, R29, R30,
+    R31
+};
+
+/* Register aliases */
+enum {
+    R_ZERO = R0,
+    R_SP = R1,
+    R_FP = R2,
+    R_LR = R9,
+    R_RV = R11,
+    R_RVH = R12
+};
+
+/* Unit presece register */
+enum {
+    UPR_UP = (1 << 0),
+    UPR_DCP = (1 << 1),
+    UPR_ICP = (1 << 2),
+    UPR_DMP = (1 << 3),
+    UPR_IMP = (1 << 4),
+    UPR_MP = (1 << 5),
+    UPR_DUP = (1 << 6),
+    UPR_PCUR = (1 << 7),
+    UPR_PMP = (1 << 8),
+    UPR_PICP = (1 << 9),
+    UPR_TTP = (1 << 10),
+    UPR_CUP = (255 << 24),
+};
+
+/* CPU configure register */
+enum {
+    CPUCFGR_NSGF = (15 << 0),
+    CPUCFGR_CGF = (1 << 4),
+    CPUCFGR_OB32S = (1 << 5),
+    CPUCFGR_OB64S = (1 << 6),
+    CPUCFGR_OF32S = (1 << 7),
+    CPUCFGR_OF64S = (1 << 8),
+    CPUCFGR_OV64S = (1 << 9),
+};
+
+/* DMMU configure register */
+enum {
+    DMMUCFGR_NTW = (3 << 0),
+    DMMUCFGR_NTS = (7 << 2),
+    DMMUCFGR_NAE = (7 << 5),
+    DMMUCFGR_CRI = (1 << 8),
+    DMMUCFGR_PRI = (1 << 9),
+    DMMUCFGR_TEIRI = (1 << 10),
+    DMMUCFGR_HTR = (1 << 11),
+};
+
+/* IMMU configure register */
+enum {
+    IMMUCFGR_NTW = (3 << 0),
+    IMMUCFGR_NTS = (7 << 2),
+    IMMUCFGR_NAE = (7 << 5),
+    IMMUCFGR_CRI = (1 << 8),
+    IMMUCFGR_PRI = (1 << 9),
+    IMMUCFGR_TEIRI = (1 << 10),
+    IMMUCFGR_HTR = (1 << 11),
+};
+
+/* Supervisor register */
+enum {
+    SR_SM = 1,
+    SR_TEE = (1 << 1),
+    SR_IEE = (1 << 2),
+    SR_DCE = (1 << 3),
+    SR_ICE = (1 << 4),
+    SR_DME = (1 << 5),
+    SR_IME = (1 << 6),
+    SR_LEE = (1 << 7),
+    SR_CE  = (1 << 8),
+    SR_F   = (1 << 9),
+    SR_CY  = (1 << 10),
+    SR_OV  = (1 << 11),
+    SR_OVE = (1 << 12),
+    SR_DSX = (1 << 13),
+    SR_EPH = (1 << 14),
+    SR_FO  = (1 << 15),
+    SR_SUMRA = (1 << 16),
+    SR_SCE = (1 << 17),
+};
+
+/* OpenRISC Hardware Capabilities */
+enum {
+    OPENRISC_FEATURE_NSGF,
+    OPENRISC_FEATURE_CGF,
+    OPENRISC_FEATURE_OB32S,
+    OPENRISC_FEATURE_OB64S,
+    OPENRISC_FEATURE_OF32S,
+    OPENRISC_FEATURE_OF64S,
+    OPENRISC_FEATURE_OV64S,
+    OPENRISC_FEATURE_OR1200,
+};
+
+typedef struct CPUOpenRISCState CPUOpenRISCState;
+struct CPUOpenRISCState {
+    target_ulong gpr[32];     /* General registers */
+    target_ulong pc;          /* Program counter */
+    target_ulong npc;         /* Next PC */
+    target_ulong ppc;         /* Prev PC */
+    target_ulong jmp_pc;      /* Jump PC */
+
+    uint32_t sr;              /* Supervisor register */
+    uint32_t vr;              /* Version register */
+    uint32_t upr;             /* Unit presence register */
+    uint32_t cpucfgr;         /* CPU configure register */
+    uint32_t dmmucfgr;        /* DMMU configure register */
+    uint32_t immucfgr;        /* IMMU configure register */
+    uint32_t flags;           /* cpu_flags, we only use it for exception
+                                 in solt so far.  */
+    uint32_t btaken;          /* the SR_F bit */
+
+    CPU_COMMON
+
+#ifndef CONFIG_USER_ONLY
+    struct QEMUTimer *timer;
+    uint32_t ttmr;          /* Timer tick mode register */
+    uint32_t ttcr;          /* Timer tick count register */
+
+    uint32_t picmr;         /* Interrupt mask register */
+    uint32_t picsr;         /* Interrupt contrl register*/
+#endif
+    uint32_t feature;       /* CPU Capabilities */
+};
+
+#define TYPE_OPENRISC_CPU "or32-cpu"
+
+#define OPENRISC_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(OpenRISCCPUClass, (klass), TYPE_OPENRISC_CPU)
+#define OPENRISC_CPU(obj) \
+    OBJECT_CHECK(OpenRISCCPU, (obj), TYPE_OPENRISC_CPU)
+#define OPENRISC_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(OpenRISCCPUClass, (obj), TYPE_OPENRISC_CPU)
+
+/**
+ * OpenRISCCPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * A OpenRISC CPU model.
+ */
+typedef struct OpenRISCCPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    void (*parent_reset)(CPUState *cpu);
+} OpenRISCCPUClass;
+
+/**
+ * OpenRISCCPU:
+ * @env: #CPUOpenRISCState
+ *
+ * A OpenRISC CPU.
+ */
+typedef struct OpenRISCCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUOpenRISCState env;
+} OpenRISCCPU;
+
+static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env)
+{
+    return OPENRISC_CPU(container_of(env, OpenRISCCPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(openrisc_env_get_cpu(e))
+
+void openrisc_cpu_realize(Object *obj, Error **errp);
+
+void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf);
+OpenRISCCPU *cpu_openrisc_init(const char *cpu_model);
+int cpu_openrisc_exec(CPUOpenRISCState *s);
+void do_interrupt(CPUOpenRISCState *env);
+void openrisc_translate_init(void);
+
+#define cpu_list cpu_openrisc_list
+#define cpu_exec cpu_openrisc_exec
+#define cpu_gen_code cpu_openrisc_gen_code
+
+#define CPU_SAVE_VERSION 1
+
+#ifndef CONFIG_USER_ONLY
+void cpu_openrisc_pic_reset(CPUOpenRISCState *env);
+
+void cpu_openrisc_timer_reset(CPUOpenRISCState *env);
+
+void openrisc_mmu_init(CPUOpenRISCState *env);
+#endif
+
+static inline CPUOpenRISCState *cpu_init(const char *cpu_model)
+{
+    OpenRISCCPU *cpu = cpu_openrisc_init(cpu_model);
+    if (cpu) {
+        return &cpu->env;
+    }
+    return NULL;
+}
+
+#include "cpu-all.h"
+
+static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
+                                        target_ulong *pc,
+                                        target_ulong *cs_base, int *flags)
+{
+    *pc = env->pc;
+    *cs_base = 0;
+    *flags = 0;
+}
+
+static inline int cpu_mmu_index(CPUOpenRISCState *env)
+{
+    return 0;
+}
+
+static inline bool cpu_has_work(CPUOpenRISCState *env)
+{
+    return true;
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUOpenRISCState *env, TranslationBlock *tb)
+{
+    env->pc = tb->pc;
+}
+
+#endif /* CPU_OPENRISC_H */
diff --git a/target-openrisc/intrpt.c b/target-openrisc/intrpt.c
new file mode 100644
index 0000000..a3bb7f8
--- /dev/null
+++ b/target-openrisc/intrpt.c
@@ -0,0 +1,30 @@
+/*
+ *  OpenRISC interrupt.
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@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 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/>.
+ */
+
+#include "cpu.h"
+#include "qemu-common.h"
+#include "gdbstub.h"
+#include "host-utils.h"
+#ifndef CONFIG_USER_ONLY
+#include "hw/loader.h"
+#endif
+
+void do_interrupt(CPUOpenRISCState *env)
+{
+}
diff --git a/target-openrisc/machine.c b/target-openrisc/machine.c
new file mode 100644
index 0000000..11bf275
--- /dev/null
+++ b/target-openrisc/machine.c
@@ -0,0 +1,30 @@
+/*
+ *  OpenRISC Machine
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@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 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/>.
+ */
+
+#include "hw/hw.h"
+#include "hw/boards.h"
+
+void cpu_save(QEMUFile *f, void *opaque)
+{
+}
+
+int cpu_load(QEMUFile *f, void *opaque, int version_id)
+{
+    return 0;
+}
diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c
new file mode 100644
index 0000000..cd82b7a
--- /dev/null
+++ b/target-openrisc/mmu.c
@@ -0,0 +1,39 @@
+/*
+ *  OpenRISC MMU.
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
+ *                          Zhizhou Zhang <etouzh@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 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/>.
+ */
+
+#include "cpu.h"
+#include "qemu-common.h"
+#include "gdbstub.h"
+#include "host-utils.h"
+#ifndef CONFIG_USER_ONLY
+#include "hw/loader.h"
+#endif
+
+#ifndef CONFIG_USER_ONLY
+target_phys_addr_t cpu_get_phys_page_debug(CPUOpenRISCState *env,
+                                           target_ulong addr)
+{
+    return addr;
+}
+
+void openrisc_mmu_init(CPUOpenRISCState *env)
+{
+}
+#endif
diff --git a/target-openrisc/mmu_helper.c b/target-openrisc/mmu_helper.c
new file mode 100644
index 0000000..f526ba8
--- /dev/null
+++ b/target-openrisc/mmu_helper.c
@@ -0,0 +1,43 @@
+/*
+ *  OpenRISC MMU helper routines
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
+ *                          Zhizhou Zhang <etouzh@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 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/>.
+ */
+
+#include "cpu.h"
+
+#ifndef CONFIG_USER_ONLY
+#include "softmmu_exec.h"
+#define MMUSUFFIX _mmu
+
+#define SHIFT 0
+#include "softmmu_template.h"
+
+#define SHIFT 1
+#include "softmmu_template.h"
+
+#define SHIFT 2
+#include "softmmu_template.h"
+
+#define SHIFT 3
+#include "softmmu_template.h"
+
+void tlb_fill(CPUOpenRISCState *env, target_ulong addr, int is_write,
+              int mmu_idx, uintptr_t retaddr)
+{
+}
+#endif
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
new file mode 100644
index 0000000..1d87d76
--- /dev/null
+++ b/target-openrisc/translate.c
@@ -0,0 +1,75 @@
+/*
+ *  OpenRISC translation
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
+ *                          Feng Gao <gf91597@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 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/>.
+ */
+
+#include "cpu.h"
+#include "exec-all.h"
+#include "disas.h"
+#include "tcg-op.h"
+#include "qemu-common.h"
+#include "qemu-log.h"
+#include "config.h"
+
+#define OPENRISC_DISAS
+
+#ifdef OPENRISC_DISAS
+#  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
+#else
+#  define LOG_DIS(...) do { } while (0)
+#endif
+
+void openrisc_translate_init(void)
+{
+}
+
+static inline void gen_intermediate_code_internal(CPUOpenRISCState *env,
+                                                  TranslationBlock *tb,
+                                                  int search_pc)
+{
+}
+
+void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
+{
+    gen_intermediate_code_internal(env, tb, 0);
+}
+
+void gen_intermediate_code_pc(CPUOpenRISCState *env,
+                              struct TranslationBlock *tb)
+{
+    gen_intermediate_code_internal(env, tb, 1);
+}
+
+void cpu_dump_state(CPUOpenRISCState *env, FILE *f,
+                    fprintf_function cpu_fprintf,
+                    int flags)
+{
+    int i;
+    uint32_t *regs = env->gpr;
+    cpu_fprintf(f, "PC=%08x\n", env->pc);
+    for (i = 0; i < 32; ++i) {
+        cpu_fprintf(f, "R%02d=%08x%c", i, regs[i],
+                    (i % 4) == 3 ? '\n' : ' ');
+    }
+}
+
+void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb,
+                          int pc_pos)
+{
+    env->pc = gen_opc_pc[pc_pos];
+}
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 02/16] target-or32: Add target machine
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 01/16] target-or32: Add target stubs and cpu support Jia Liu
@ 2012-06-21  2:57 ` Jia Liu
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 03/16] target-or32: Add MMU support Jia Liu
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:57 UTC (permalink / raw)
  To: qemu-devel

Add OpenRISC machine.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 target-openrisc/cpu.h     |   67 ++++++++++++++++++++++++++++++++++++++++++++-
 target-openrisc/machine.c |   22 ++++++++++++++-
 2 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 0b8e836..58c8081 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -48,6 +48,15 @@ struct CPUOpenRISCState;
 #define TARGET_PHYS_ADDR_SPACE_BITS 32
 #define TARGET_VIRT_ADDR_SPACE_BITS 32
 
+#define SET_FP_CAUSE(reg, v)    do {\
+                                    (reg) = ((reg) & ~(0x3f << 12)) | \
+                                            ((v & 0x3f) << 12);\
+                                } while (0)
+#define GET_FP_ENABLE(reg)       (((reg) >>  7) & 0x1f)
+#define UPDATE_FP_FLAGS(reg, v)   do {\
+                                      (reg) |= ((v & 0x1f) << 2);\
+                                  } while (0)
+
 /* Internal flags, delay slot flag */
 #define D_FLAG    1
 
@@ -121,6 +130,40 @@ enum {
     IMMUCFGR_HTR = (1 << 11),
 };
 
+/* Float point control status register */
+enum {
+    FPCSR_FPEE = 1,
+    FPCSR_RM = (3 << 1),
+    FPCSR_OVF = (1 << 3),
+    FPCSR_UNF = (1 << 4),
+    FPCSR_SNF = (1 << 5),
+    FPCSR_QNF = (1 << 6),
+    FPCSR_ZF = (1 << 7),
+    FPCSR_IXF = (1 << 8),
+    FPCSR_IVF = (1 << 9),
+    FPCSR_INF = (1 << 10),
+    FPCSR_DZF = (1 << 11),
+};
+
+/* Exceptions indices */
+enum {
+    EXCP_RESET    = 0x1,
+    EXCP_BUSERR   = 0x2,
+    EXCP_DPF      = 0x3,
+    EXCP_IPF      = 0x4,
+    EXCP_TICK     = 0x5,
+    EXCP_ALIGN    = 0x6,
+    EXCP_ILLEGAL  = 0x7,
+    EXCP_INT      = 0x8,
+    EXCP_DTLBMISS = 0x9,
+    EXCP_ITLBMISS = 0xa,
+    EXCP_RANGE    = 0xb,
+    EXCP_SYSCALL  = 0xc,
+    EXCP_FPE      = 0xd,
+    EXCP_TRAP     = 0xe,
+    EXCP_NR,
+};
+
 /* Supervisor register */
 enum {
     SR_SM = 1,
@@ -155,6 +198,14 @@ enum {
     OPENRISC_FEATURE_OR1200,
 };
 
+/* Tick Timer Mode Register */
+enum {
+    TTMR_TP = (0xfffffff),
+    TTMR_IP = (1 << 28),
+    TTMR_IE = (1 << 29),
+    TTMR_M  = (3 << 30),
+};
+
 typedef struct CPUOpenRISCState CPUOpenRISCState;
 struct CPUOpenRISCState {
     target_ulong gpr[32];     /* General registers */
@@ -163,12 +214,25 @@ struct CPUOpenRISCState {
     target_ulong ppc;         /* Prev PC */
     target_ulong jmp_pc;      /* Jump PC */
 
+    target_ulong machi;       /* Multiply register MACHI */
+    target_ulong maclo;       /* Multiply register MACLO */
+
+    target_ulong fpmaddhi;    /* Multiply and add float register FPMADDHI */
+    target_ulong fpmaddlo;    /* Multiply and add float register FPMADDLO */
+
+    target_ulong epcr;        /* Exception PC register */
+    target_ulong eear;        /* Exception EA register */
+
     uint32_t sr;              /* Supervisor register */
     uint32_t vr;              /* Version register */
     uint32_t upr;             /* Unit presence register */
     uint32_t cpucfgr;         /* CPU configure register */
     uint32_t dmmucfgr;        /* DMMU configure register */
     uint32_t immucfgr;        /* IMMU configure register */
+    uint32_t esr;             /* Exception supervisor register */
+    uint32_t fpcsr;           /* Float register */
+    float_status fp_status;
+
     uint32_t flags;           /* cpu_flags, we only use it for exception
                                  in solt so far.  */
     uint32_t btaken;          /* the SR_F bit */
@@ -269,7 +333,8 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
 {
     *pc = env->pc;
     *cs_base = 0;
-    *flags = 0;
+    /* D_FLAG -- branch instruction exception */
+    *flags = (env->flags & D_FLAG);
 }
 
 static inline int cpu_mmu_index(CPUOpenRISCState *env)
diff --git a/target-openrisc/machine.c b/target-openrisc/machine.c
index 11bf275..e5d59a7 100644
--- a/target-openrisc/machine.c
+++ b/target-openrisc/machine.c
@@ -20,11 +20,31 @@
 #include "hw/hw.h"
 #include "hw/boards.h"
 
+static const VMStateDescription vmstate_cpu = {
+    .name = "cpu",
+    .version_id = CPU_SAVE_VERSION,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(gpr, CPUOpenRISCState, 32),
+        VMSTATE_UINT32(sr, CPUOpenRISCState),
+        VMSTATE_UINT32(epcr, CPUOpenRISCState),
+        VMSTATE_UINT32(eear, CPUOpenRISCState),
+        VMSTATE_UINT32(esr, CPUOpenRISCState),
+        VMSTATE_UINT32(fpcsr, CPUOpenRISCState),
+        VMSTATE_UINT32(pc, CPUOpenRISCState),
+        VMSTATE_UINT32(npc, CPUOpenRISCState),
+        VMSTATE_UINT32(ppc, CPUOpenRISCState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 void cpu_save(QEMUFile *f, void *opaque)
 {
+    vmstate_save_state(f, &vmstate_cpu, opaque);
 }
 
 int cpu_load(QEMUFile *f, void *opaque, int version_id)
 {
-    return 0;
+    return vmstate_load_state(f, &vmstate_cpu, opaque, version_id);
 }
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 03/16] target-or32: Add MMU support
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 01/16] target-or32: Add target stubs and cpu support Jia Liu
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 02/16] target-or32: Add target machine Jia Liu
@ 2012-06-21  2:57 ` Jia Liu
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 04/16] target-or32: Add interrupt support Jia Liu
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:57 UTC (permalink / raw)
  To: qemu-devel

Add OpenRISC MMU support.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 target-openrisc/cpu.h        |   75 +++++++++++++++-
 target-openrisc/mmu.c        |  199 +++++++++++++++++++++++++++++++++++++++++-
 target-openrisc/mmu_helper.c |   20 +++++
 3 files changed, 292 insertions(+), 2 deletions(-)

diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 58c8081..dbb3f17 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -43,6 +43,12 @@ struct CPUOpenRISCState;
 
 #define NB_MMU_MODES    3
 
+enum {
+    MMU_NOMMU_IDX = 0,
+    MMU_SUPERVISOR_IDX = 1,
+    MMU_USER_IDX = 2,
+};
+
 #define TARGET_PAGE_BITS 13
 
 #define TARGET_PHYS_ADDR_SPACE_BITS 32
@@ -206,6 +212,54 @@ enum {
     TTMR_M  = (3 << 30),
 };
 
+/* TLB size */
+enum {
+    DTLB_WAYS = 1,
+    DTLB_SIZE = 64,
+    DTLB_MASK = (DTLB_SIZE-1),
+    ITLB_WAYS = 1,
+    ITLB_SIZE = 64,
+    ITLB_MASK = (ITLB_SIZE-1),
+};
+
+/* TLB prot */
+enum {
+    URE = (1 << 6),
+    UWE = (1 << 7),
+    SRE = (1 << 8),
+    SWE = (1 << 9),
+
+    SXE = (1 << 6),
+    UXE = (1 << 7),
+};
+
+/* check if tlb available */
+enum {
+    TLBRET_INVALID = -3,
+    TLBRET_NOMATCH = -2,
+    TLBRET_BADADDR = -1,
+    TLBRET_MATCH = 0
+};
+
+typedef struct OpenRISCTLBEntry {
+    uint32_t mr;
+    uint32_t tr;
+} OpenRISCTLBEntry;
+
+#ifndef CONFIG_USER_ONLY
+typedef struct CPUOpenRISCTLBContext {
+    OpenRISCTLBEntry itlb[ITLB_WAYS][ITLB_SIZE];
+    OpenRISCTLBEntry dtlb[DTLB_WAYS][DTLB_SIZE];
+
+    int (*map_address_code)(struct CPUOpenRISCState *env,
+                            target_phys_addr_t *physical, int *prot,
+                            target_ulong address, int rw);
+    int (*map_address_data)(struct CPUOpenRISCState *env,
+                            target_phys_addr_t *physical, int *prot,
+                            target_ulong address, int rw);
+} CPUOpenRISCTLBContext;
+#endif
+
 typedef struct CPUOpenRISCState CPUOpenRISCState;
 struct CPUOpenRISCState {
     target_ulong gpr[32];     /* General registers */
@@ -240,6 +294,8 @@ struct CPUOpenRISCState {
     CPU_COMMON
 
 #ifndef CONFIG_USER_ONLY
+    CPUOpenRISCTLBContext * tlb;
+
     struct QEMUTimer *timer;
     uint32_t ttmr;          /* Timer tick mode register */
     uint32_t ttcr;          /* Timer tick count register */
@@ -301,19 +357,33 @@ OpenRISCCPU *cpu_openrisc_init(const char *cpu_model);
 int cpu_openrisc_exec(CPUOpenRISCState *s);
 void do_interrupt(CPUOpenRISCState *env);
 void openrisc_translate_init(void);
+int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, target_ulong address,
+                                  int rw, int mmu_idx);
 
 #define cpu_list cpu_openrisc_list
 #define cpu_exec cpu_openrisc_exec
 #define cpu_gen_code cpu_openrisc_gen_code
+#define cpu_handle_mmu_fault cpu_openrisc_handle_mmu_fault
 
 #define CPU_SAVE_VERSION 1
 
 #ifndef CONFIG_USER_ONLY
 void cpu_openrisc_pic_reset(CPUOpenRISCState *env);
+void cpu_openrisc_store_picsr(CPUOpenRISCState *env, uint32_t value);
+void cpu_openrisc_store_picmr(CPUOpenRISCState *env, uint32_t value);
 
 void cpu_openrisc_timer_reset(CPUOpenRISCState *env);
+void cpu_openrisc_store_count(CPUOpenRISCState *env, target_ulong count);
+void cpu_openrisc_store_compare(CPUOpenRISCState *env, target_ulong value);
+uint32_t cpu_openrisc_get_count(CPUOpenRISCState *env);
 
 void openrisc_mmu_init(CPUOpenRISCState *env);
+int get_phys_nommu(CPUOpenRISCState *env, target_phys_addr_t *physical,
+                   int *prot, target_ulong address, int rw);
+int get_phys_code(CPUOpenRISCState *env, target_phys_addr_t *physical,
+                  int *prot, target_ulong address, int rw);
+int get_phys_data(CPUOpenRISCState *env, target_phys_addr_t *physical,
+                  int *prot, target_ulong address, int rw);
 #endif
 
 static inline CPUOpenRISCState *cpu_init(const char *cpu_model)
@@ -339,7 +409,10 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
 
 static inline int cpu_mmu_index(CPUOpenRISCState *env)
 {
-    return 0;
+    if (!(env->sr & SR_IME)) {
+        return MMU_NOMMU_IDX;
+    }
+    return (env->sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
 }
 
 static inline bool cpu_has_work(CPUOpenRISCState *env)
diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c
index cd82b7a..ecef2e1 100644
--- a/target-openrisc/mmu.c
+++ b/target-openrisc/mmu.c
@@ -27,13 +27,210 @@
 #endif
 
 #ifndef CONFIG_USER_ONLY
+int get_phys_nommu(CPUOpenRISCState *env, target_phys_addr_t *physical,
+                   int *prot, target_ulong address, int rw)
+{
+    *physical = address;
+    *prot = PAGE_READ | PAGE_WRITE;
+    return TLBRET_MATCH;
+}
+
+int get_phys_code(CPUOpenRISCState *env, target_phys_addr_t *physical,
+                  int *prot, target_ulong address, int rw)
+{
+    int vpn = address >> TARGET_PAGE_BITS;
+    int idx = vpn & ITLB_MASK;
+    int right = 0;
+
+    if ((env->tlb->itlb[0][idx].mr >> TARGET_PAGE_BITS) != vpn) {
+        return TLBRET_NOMATCH;
+    }
+    if (!(env->tlb->itlb[0][idx].mr & 1)) {
+        return TLBRET_INVALID;
+    }
+
+    if (env->sr & SR_SM) { /* supervisor mode */
+        if (env->tlb->itlb[0][idx].tr & SXE) {
+            right |= PAGE_EXEC;
+        }
+    } else {
+        if (env->tlb->itlb[0][idx].tr & UXE) {
+            right |= PAGE_EXEC;
+        }
+    }
+
+    if ((rw & 2) && ((right & PAGE_EXEC) == 0)) {
+        return TLBRET_BADADDR;
+    }
+
+    *physical = (env->tlb->itlb[0][idx].tr & TARGET_PAGE_MASK) |
+                (address & (TARGET_PAGE_SIZE-1));
+    *prot = right;
+    return TLBRET_MATCH;
+}
+
+int get_phys_data(CPUOpenRISCState *env, target_phys_addr_t *physical,
+                  int *prot, target_ulong address, int rw)
+{
+    int vpn = address >> TARGET_PAGE_BITS;
+    int idx = vpn & DTLB_MASK;
+    int right = 0;
+
+    if ((env->tlb->dtlb[0][idx].mr >> TARGET_PAGE_BITS) != vpn) {
+        return TLBRET_NOMATCH;
+    }
+    if (!(env->tlb->dtlb[0][idx].mr & 1)) {
+        return TLBRET_INVALID;
+    }
+
+    if (env->sr & SR_SM) { /* supervisor mode */
+        if (env->tlb->dtlb[0][idx].tr & SRE) {
+            right |= PAGE_READ;
+        }
+        if (env->tlb->dtlb[0][idx].tr & SWE) {
+            right |= PAGE_WRITE;
+        }
+    } else {
+        if (env->tlb->dtlb[0][idx].tr & URE) {
+            right |= PAGE_READ;
+        }
+        if (env->tlb->dtlb[0][idx].tr & UWE) {
+            right |= PAGE_WRITE;
+        }
+    }
+
+    if ((rw & 0) && ((right & PAGE_READ) == 0)) {
+        return TLBRET_BADADDR;
+    }
+    if ((rw & 1) && ((right & PAGE_WRITE) == 0)) {
+        return TLBRET_BADADDR;
+    }
+
+    *physical = (env->tlb->dtlb[0][idx].tr & TARGET_PAGE_MASK) |
+                (address & (TARGET_PAGE_SIZE-1));
+    *prot = right;
+    return TLBRET_MATCH;
+}
+
+static int get_physical_address(CPUOpenRISCState *env,
+                                target_phys_addr_t *physical,
+                                int *prot, target_ulong address,
+                                int rw)
+{
+    int ret = TLBRET_MATCH;
+
+    /* [0x0000--0x2000]: unmapped */
+    if (address < 0x2000 && (env->sr & SR_SM)) {
+        *physical = address;
+        *prot = PAGE_READ | PAGE_WRITE;
+        return ret;
+    }
+
+    if (rw == 2) {    /* ITLB */
+       *physical = 0;
+        ret = env->tlb->map_address_code(env, physical,
+                                         prot, address, rw);
+    } else {          /* DTLB */
+        ret = env->tlb->map_address_data(env, physical,
+                                         prot, address, rw);
+    }
+
+    return ret;
+}
+#endif
+
+static void raise_mmu_exception(CPUOpenRISCState *env, target_ulong address,
+                                int rw, int tlb_error)
+{
+    int exception = 0;
+
+    switch (tlb_error) {
+    default:
+        if (rw == 2) {
+            exception = EXCP_IPF;
+        } else {
+            exception = EXCP_DPF;
+        }
+        break;
+#ifndef CONFIG_USER_ONLY
+    case TLBRET_BADADDR:
+        if (rw == 2) {
+            exception = EXCP_IPF;
+        } else {
+            exception = EXCP_DPF;
+        }
+        break;
+    case TLBRET_INVALID:
+    case TLBRET_NOMATCH:
+        /* No TLB match for a mapped address */
+        if (rw == 2) {
+            exception = EXCP_ITLBMISS;
+        } else {
+            exception = EXCP_DTLBMISS;
+        }
+        break;
+#endif
+    }
+
+    env->exception_index = exception;
+    env->eear = address;
+}
+
+#ifndef CONFIG_USER_ONLY
+int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
+                                  target_ulong address, int rw, int mmu_idx)
+{
+    int ret = 0;
+    target_phys_addr_t physical = 0;
+    int prot = 0;
+
+    ret = get_physical_address(env, &physical, &prot,
+                               address, rw);
+
+    if (ret == TLBRET_MATCH) {
+        tlb_set_page(env, address & TARGET_PAGE_MASK,
+                     physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
+                     mmu_idx, TARGET_PAGE_SIZE);
+        ret = 0;
+    } else if (ret < 0) {
+        raise_mmu_exception(env, address, rw, ret);
+        ret = 1;
+    }
+
+    return ret;
+}
+#else
+int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
+                                  target_ulong address, int rw, int mmu_idx)
+{
+    int ret = 0;
+
+    raise_mmu_exception(env, address, rw, ret);
+    ret = 1;
+
+    return ret;
+}
+#endif
+
+#ifndef CONFIG_USER_ONLY
 target_phys_addr_t cpu_get_phys_page_debug(CPUOpenRISCState *env,
                                            target_ulong addr)
 {
-    return addr;
+    target_phys_addr_t phys_addr;
+    int prot;
+
+    if (get_physical_address(env, &phys_addr, &prot, addr, 0)) {
+        return -1;
+    }
+
+    return phys_addr;
 }
 
 void openrisc_mmu_init(CPUOpenRISCState *env)
 {
+    env->tlb = g_malloc0(sizeof(CPUOpenRISCTLBContext));
+
+    env->tlb->map_address_code = &get_phys_nommu;
+    env->tlb->map_address_data = &get_phys_nommu;
 }
 #endif
diff --git a/target-openrisc/mmu_helper.c b/target-openrisc/mmu_helper.c
index f526ba8..29387e3 100644
--- a/target-openrisc/mmu_helper.c
+++ b/target-openrisc/mmu_helper.c
@@ -39,5 +39,25 @@
 void tlb_fill(CPUOpenRISCState *env, target_ulong addr, int is_write,
               int mmu_idx, uintptr_t retaddr)
 {
+    TranslationBlock *tb;
+    unsigned long pc;
+    int ret;
+
+    ret = cpu_openrisc_handle_mmu_fault(env, addr, is_write, mmu_idx);
+
+    if (ret) {
+        if (retaddr) {
+            /* now we have a real cpu fault.  */
+            pc = (unsigned long)retaddr;
+            tb = tb_find_pc(pc);
+            if (tb) {
+                /* the PC is inside the translated code. It means that we
+                   have a virtual CPU fault.  */
+                cpu_restore_state(tb, env, pc);
+            }
+        }
+        /* Raise Exception.  */
+        cpu_loop_exit(env);
+    }
 }
 #endif
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 04/16] target-or32: Add interrupt support
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
                   ` (2 preceding siblings ...)
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 03/16] target-or32: Add MMU support Jia Liu
@ 2012-06-21  2:57 ` Jia Liu
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 05/16] target-or32: Add exception support Jia Liu
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:57 UTC (permalink / raw)
  To: qemu-devel

Add OpenRISC interrupt support.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 cpu-exec.c                      |   17 +++++++++++++
 target-openrisc/Makefile.objs   |    2 +-
 target-openrisc/cpu.h           |    9 ++++++-
 target-openrisc/helper.h        |   25 +++++++++++++++++++
 target-openrisc/intrpt.c        |   44 +++++++++++++++++++++++++++++++++
 target-openrisc/intrpt_helper.c |   52 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 147 insertions(+), 2 deletions(-)
 create mode 100644 target-openrisc/helper.h
 create mode 100644 target-openrisc/intrpt_helper.c

diff --git a/cpu-exec.c b/cpu-exec.c
index 7d0d87b..1d2fe6b 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -378,6 +378,23 @@ int cpu_exec(CPUArchState *env)
                         do_interrupt(env);
                         next_tb = 0;
                     }
+#elif defined(TARGET_OPENRISC)
+                    {
+                        int idx = -1;
+                        if ((interrupt_request & CPU_INTERRUPT_HARD)
+                            && (env->sr & SR_IEE)) {
+                            idx = EXCP_INT;
+                        }
+                        if ((interrupt_request & CPU_INTERRUPT_TIMER)
+                            && (env->sr & SR_TEE)) {
+                            idx = EXCP_TICK;
+                        }
+                        if (idx >= 0) {
+                            env->exception_index = idx;
+                            do_interrupt(env);
+                            next_tb = 0;
+                        }
+                    }
 #elif defined(TARGET_SPARC)
                     if (interrupt_request & CPU_INTERRUPT_HARD) {
                         if (cpu_interrupts_enabled(env) &&
diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs
index 21b76b2..65f9391 100644
--- a/target-openrisc/Makefile.objs
+++ b/target-openrisc/Makefile.objs
@@ -1,3 +1,3 @@
 obj-$(CONFIG_SOFTMMU) += machine.o
 obj-y += cpu.o intrpt.o mmu.o translate.o
-obj-y += mmu_helper.o
+obj-y += intrpt_helper.o mmu_helper.o
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index dbb3f17..d499dc4 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -66,6 +66,10 @@ enum {
 /* Internal flags, delay slot flag */
 #define D_FLAG    1
 
+/* Interrupt */
+#define NR_IRQS  32
+#define PIC_MASK 0xFFFFFFFF
+
 /* Verison Register */
 #define SPR_VR       0xFFFF003F
 
@@ -304,6 +308,7 @@ struct CPUOpenRISCState {
     uint32_t picsr;         /* Interrupt contrl register*/
 #endif
     uint32_t feature;       /* CPU Capabilities */
+    void *irq[32];          /* Interrupt irq input */
 };
 
 #define TYPE_OPENRISC_CPU "or32-cpu"
@@ -415,9 +420,11 @@ static inline int cpu_mmu_index(CPUOpenRISCState *env)
     return (env->sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
 }
 
+#define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
 static inline bool cpu_has_work(CPUOpenRISCState *env)
 {
-    return true;
+    return env->interrupt_request & (CPU_INTERRUPT_HARD |
+                                     CPU_INTERRUPT_TIMER);
 }
 
 #include "exec-all.h"
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
new file mode 100644
index 0000000..16d99b6
--- /dev/null
+++ b/target-openrisc/helper.h
@@ -0,0 +1,25 @@
+/*
+ *  OpenRISC helper defines
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@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 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/>.
+ */
+
+#include "def-helper.h"
+
+/* interrupt */
+DEF_HELPER_FLAGS_1(rfe, 0, void, env)
+
+#include "def-helper.h"
diff --git a/target-openrisc/intrpt.c b/target-openrisc/intrpt.c
index a3bb7f8..9b02618 100644
--- a/target-openrisc/intrpt.c
+++ b/target-openrisc/intrpt.c
@@ -27,4 +27,48 @@
 
 void do_interrupt(CPUOpenRISCState *env)
 {
+#ifndef CONFIG_USER_ONLY
+    if (env->flags & D_FLAG) { /* Delay Slot insn */
+        env->flags &= ~D_FLAG;
+        env->sr |= SR_DSX;
+        if (env->exception_index == EXCP_TICK    ||
+            env->exception_index == EXCP_INT     ||
+            env->exception_index == EXCP_SYSCALL ||
+            env->exception_index == EXCP_FPE) {
+            env->epcr = env->jmp_pc;
+        } else {
+            env->epcr = env->pc - 4;
+        }
+    } else {
+        if (env->exception_index == EXCP_TICK    ||
+            env->exception_index == EXCP_INT     ||
+            env->exception_index == EXCP_SYSCALL ||
+            env->exception_index == EXCP_FPE) {
+            env->epcr = env->npc;
+        } else {
+            env->epcr = env->pc;
+        }
+    }
+
+    /* For machine-state changed between user-mode and supervisor mode,
+       we need flush TLB when we enter&exit EXCP.  */
+    tlb_flush(env, 1);
+
+    env->esr = env->sr;
+    env->sr &= ~SR_DME;
+    env->sr &= ~SR_IME;
+    env->sr |= SR_SM;
+    env->sr &= ~SR_IEE;
+    env->sr &= ~SR_TEE;
+    env->tlb->map_address_data = &get_phys_nommu;
+    env->tlb->map_address_code = &get_phys_nommu;
+
+    if (env->exception_index > 0 && env->exception_index < EXCP_NR) {
+        env->pc = (env->exception_index << 8);
+    } else {
+        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
+    }
+#endif
+
+    env->exception_index = -1;
 }
diff --git a/target-openrisc/intrpt_helper.c b/target-openrisc/intrpt_helper.c
new file mode 100644
index 0000000..fca0202
--- /dev/null
+++ b/target-openrisc/intrpt_helper.c
@@ -0,0 +1,52 @@
+/*
+ *  OpenRISC interrupt helper routines
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
+ *                          Feng Gao <gf91597@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 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/>.
+ */
+
+#include "cpu.h"
+#include "helper.h"
+
+void HELPER(rfe)(CPUOpenRISCState *env)
+{
+#ifndef CONFIG_USER_ONLY
+    int need_flush_tlb = (env->sr & (SR_SM | SR_IME | SR_DME)) ^
+                         (env->esr & (SR_SM | SR_IME | SR_DME));
+#endif
+    env->pc = env->epcr;
+    env->npc = env->epcr;
+    env->sr = env->esr;
+
+#ifndef CONFIG_USER_ONLY
+    if (env->sr & SR_DME) {
+        env->tlb->map_address_data = &get_phys_data;
+    } else {
+        env->tlb->map_address_data = &get_phys_nommu;
+    }
+
+    if (env->sr & SR_IME) {
+        env->tlb->map_address_code = &get_phys_code;
+    } else {
+        env->tlb->map_address_code = &get_phys_nommu;
+    }
+
+    if (need_flush_tlb) {
+        tlb_flush(env, 1);
+    }
+#endif
+    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+}
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 05/16] target-or32: Add exception support
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
                   ` (3 preceding siblings ...)
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 04/16] target-or32: Add interrupt support Jia Liu
@ 2012-06-21  2:57 ` Jia Liu
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 06/16] target-or32: Add int instruction helpers Jia Liu
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:57 UTC (permalink / raw)
  To: qemu-devel

Add OpenRISC exception support.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 target-openrisc/Makefile.objs |    4 ++--
 target-openrisc/excp.c        |   27 +++++++++++++++++++++++++++
 target-openrisc/excp.h        |   28 ++++++++++++++++++++++++++++
 target-openrisc/excp_helper.c |   27 +++++++++++++++++++++++++++
 target-openrisc/helper.h      |    3 +++
 5 files changed, 87 insertions(+), 2 deletions(-)
 create mode 100644 target-openrisc/excp.c
 create mode 100644 target-openrisc/excp.h
 create mode 100644 target-openrisc/excp_helper.c

diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs
index 65f9391..382190a 100644
--- a/target-openrisc/Makefile.objs
+++ b/target-openrisc/Makefile.objs
@@ -1,3 +1,3 @@
 obj-$(CONFIG_SOFTMMU) += machine.o
-obj-y += cpu.o intrpt.o mmu.o translate.o
-obj-y += intrpt_helper.o mmu_helper.o
+obj-y += cpu.o excp.o intrpt.o mmu.o translate.o
+obj-y += excp_helper.o intrpt_helper.o mmu_helper.o
diff --git a/target-openrisc/excp.c b/target-openrisc/excp.c
new file mode 100644
index 0000000..6d8c5dd
--- /dev/null
+++ b/target-openrisc/excp.c
@@ -0,0 +1,27 @@
+/*
+ *  OpenRISC exception.
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@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 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/>.
+ */
+
+#include "cpu.h"
+#include "excp.h"
+
+void QEMU_NORETURN raise_exception(CPUOpenRISCState *env, uint32_t excp)
+{
+    env->exception_index = excp;
+    cpu_loop_exit(env);
+}
diff --git a/target-openrisc/excp.h b/target-openrisc/excp.h
new file mode 100644
index 0000000..885203b
--- /dev/null
+++ b/target-openrisc/excp.h
@@ -0,0 +1,28 @@
+/*
+ *  OpenRISC exception header.
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@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 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 QEMU_OPENRISC_EXCP_H
+#define QEMU_OPENRISC_EXCP_H
+
+#include "cpu.h"
+#include "qemu-common.h"
+
+void QEMU_NORETURN raise_exception(CPUOpenRISCState *env, uint32_t excp);
+
+#endif /* QEMU_OPENRISC_EXCP_H */
diff --git a/target-openrisc/excp_helper.c b/target-openrisc/excp_helper.c
new file mode 100644
index 0000000..c7d4110
--- /dev/null
+++ b/target-openrisc/excp_helper.c
@@ -0,0 +1,27 @@
+/*
+ *  OpenRISC exception helper routines
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@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 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/>.
+ */
+
+#include "cpu.h"
+#include "helper.h"
+#include "excp.h"
+
+void HELPER(exception)(CPUOpenRISCState *env, uint32_t excp)
+{
+    raise_exception(env, excp);
+}
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index 16d99b6..4e2a49f 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -19,6 +19,9 @@
 
 #include "def-helper.h"
 
+/* exception */
+DEF_HELPER_FLAGS_2(exception, 0, void, env, i32)
+
 /* interrupt */
 DEF_HELPER_FLAGS_1(rfe, 0, void, env)
 
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 06/16] target-or32: Add int instruction helpers
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
                   ` (4 preceding siblings ...)
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 05/16] target-or32: Add exception support Jia Liu
@ 2012-06-21  2:57 ` Jia Liu
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 07/16] target-or32: Add float " Jia Liu
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:57 UTC (permalink / raw)
  To: qemu-devel

Add OpenRISC int instruction helpers.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 target-openrisc/Makefile.objs |    2 +-
 target-openrisc/helper.h      |    5 +++
 target-openrisc/int_helper.c  |   85 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+), 1 deletion(-)
 create mode 100644 target-openrisc/int_helper.c

diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs
index 382190a..4286462 100644
--- a/target-openrisc/Makefile.objs
+++ b/target-openrisc/Makefile.objs
@@ -1,3 +1,3 @@
 obj-$(CONFIG_SOFTMMU) += machine.o
 obj-y += cpu.o excp.o intrpt.o mmu.o translate.o
-obj-y += excp_helper.o intrpt_helper.o mmu_helper.o
+obj-y += excp_helper.o int_helper.o intrpt_helper.o mmu_helper.o
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index 4e2a49f..c772951 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -22,6 +22,11 @@
 /* exception */
 DEF_HELPER_FLAGS_2(exception, 0, void, env, i32)
 
+/* int */
+DEF_HELPER_FLAGS_1(ff1, 0, tl, tl)
+DEF_HELPER_FLAGS_1(fl1, 0, tl, tl)
+DEF_HELPER_FLAGS_3(mul32, 0, tl, env, tl, tl)
+
 /* interrupt */
 DEF_HELPER_FLAGS_1(rfe, 0, void, env)
 
diff --git a/target-openrisc/int_helper.c b/target-openrisc/int_helper.c
new file mode 100644
index 0000000..09cd70a
--- /dev/null
+++ b/target-openrisc/int_helper.c
@@ -0,0 +1,85 @@
+/*
+ *  OpenRISC int helper routines
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
+ *                          Feng Gao <gf91597@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 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/>.
+ */
+
+#include "cpu.h"
+#include "helper.h"
+#include "excp.h"
+
+target_ulong HELPER(ff1)(target_ulong x)
+{
+    target_ulong n = 0;
+
+    if (x == 0) {
+        return 0;
+    }
+
+    for (n = 32; x; n--) {
+        x <<= 1;
+    }
+    return n+1;
+}
+
+target_ulong HELPER(fl1)(target_ulong x)
+{
+    target_ulong n = 0;
+
+    if (x == 0) {
+        return 0;
+    }
+
+    for (n = 0; x; n++) {
+        x >>= 1;
+    }
+    return n;
+}
+
+target_ulong HELPER(mul32)(CPUOpenRISCState *env,
+                           target_ulong ra, target_ulong rb)
+{
+    uint64_t result;
+    target_ulong high, cy;
+
+    result = ra * rb;
+    /* regisiers in or32 is 32bit, so 32 is NOT a magic number.
+       or64 is not handled in this function, and not implement yet,
+       TARGET_LONG_BITS for or64 is 64, it will break this function,
+       so, we didn't use TARGET_LONG_BITS here.  */
+    high = result >> 32;
+    cy = result >> (32 - 1);
+
+    if ((cy & 0x1) == 0x0) {
+        if (high == 0x0) {
+            return result;
+        }
+    }
+
+    if ((cy & 0x1) == 0x1) {
+        if (high == 0xffffffff) {
+            return result;
+        }
+    }
+
+    env->sr |= (SR_OV | SR_CY);
+    if (env->sr & SR_OVE) {
+        raise_exception(env, EXCP_RANGE);
+    }
+
+    return result;
+}
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 07/16] target-or32: Add float instruction helpers
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
                   ` (5 preceding siblings ...)
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 06/16] target-or32: Add int instruction helpers Jia Liu
@ 2012-06-21  2:57 ` Jia Liu
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 08/16] target-or32: Add instruction tanslation Jia Liu
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:57 UTC (permalink / raw)
  To: qemu-devel

Add OpenRISC float instruction helpers.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 target-openrisc/Makefile.objs |    2 +-
 target-openrisc/fpu_helper.c  |  275 +++++++++++++++++++++++++++++++++++++++++
 target-openrisc/helper.h      |   33 +++++
 3 files changed, 309 insertions(+), 1 deletion(-)
 create mode 100644 target-openrisc/fpu_helper.c

diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs
index 4286462..0d72c33 100644
--- a/target-openrisc/Makefile.objs
+++ b/target-openrisc/Makefile.objs
@@ -1,3 +1,3 @@
 obj-$(CONFIG_SOFTMMU) += machine.o
 obj-y += cpu.o excp.o intrpt.o mmu.o translate.o
-obj-y += excp_helper.o int_helper.o intrpt_helper.o mmu_helper.o
+obj-y += excp_helper.o fpu_helper.o int_helper.o intrpt_helper.o mmu_helper.o
diff --git a/target-openrisc/fpu_helper.c b/target-openrisc/fpu_helper.c
new file mode 100644
index 0000000..40f5857
--- /dev/null
+++ b/target-openrisc/fpu_helper.c
@@ -0,0 +1,275 @@
+/*
+ *  OpenRISC float helper routines
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
+ *                          Feng Gao <gf91597@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 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/>.
+ */
+
+#include "cpu.h"
+#include "helper.h"
+#include "excp.h"
+
+static inline uint32_t ieee_ex_to_openrisc(CPUOpenRISCState *env, int fexcp)
+{
+    int ret = 0;
+    if (fexcp) {
+        if (fexcp & float_flag_invalid) {
+            env->fpcsr |= FPCSR_IVF;
+            ret = 1;
+        }
+        if (fexcp & float_flag_overflow) {
+            env->fpcsr |= FPCSR_OVF;
+            ret = 1;
+        }
+        if (fexcp & float_flag_underflow) {
+            env->fpcsr |= FPCSR_UNF;
+            ret = 1;
+        }
+        if (fexcp & float_flag_divbyzero) {
+            env->fpcsr |= FPCSR_DZF;
+            ret = 1;
+        }
+        if (fexcp & float_flag_inexact) {
+            env->fpcsr |= FPCSR_IXF;
+            ret = 1;
+        }
+    }
+
+    return ret;
+}
+
+static inline void update_fpcsr(CPUOpenRISCState *env)
+{
+    int tmp = ieee_ex_to_openrisc(env,
+                                  get_float_exception_flags(&env->fp_status));
+
+    SET_FP_CAUSE(env->fpcsr, tmp);
+    if ((GET_FP_ENABLE(env->fpcsr) & tmp) && (env->fpcsr & FPCSR_FPEE)) {
+        helper_exception(env, EXCP_FPE);
+    } else {
+        UPDATE_FP_FLAGS(env->fpcsr, tmp);
+    }
+}
+
+uint64_t HELPER(itofd)(CPUOpenRISCState *env, uint64_t val)
+{
+    uint64_t itofd;
+    set_float_exception_flags(0, &env->fp_status);
+    itofd = int32_to_float64(val, &env->fp_status);
+    update_fpcsr(env);
+    return itofd;
+}
+
+uint32_t HELPER(itofs)(CPUOpenRISCState *env, uint32_t val)
+{
+    uint32_t itofs;
+    set_float_exception_flags(0, &env->fp_status);
+    itofs = int32_to_float32(val, &env->fp_status);
+    update_fpcsr(env);
+    return itofs;
+}
+
+uint64_t HELPER(ftoid)(CPUOpenRISCState *env, uint64_t val)
+{
+    uint64_t ftoid;
+    set_float_exception_flags(0, &env->fp_status);
+    ftoid = float32_to_int64(val, &env->fp_status);
+    update_fpcsr(env);
+    return ftoid;
+}
+
+uint32_t HELPER(ftois)(CPUOpenRISCState *env, uint32_t val)
+{
+    uint32_t ftois;
+    set_float_exception_flags(0, &env->fp_status);
+    ftois = float32_to_int32(val, &env->fp_status);
+    update_fpcsr(env);
+    return ftois;
+}
+
+#define FLOAT_OP(name, p) void helper_float_##_##p(void)
+
+#define FLOAT_CALC(name)                                                  \
+uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
+                                     uint64_t fdt0, uint64_t fdt1)        \
+{                                                                         \
+    uint64_t result;                                                      \
+    set_float_exception_flags(0, &env->fp_status);                        \
+    result = float64_ ## name(fdt0, fdt1, &env->fp_status);               \
+    update_fpcsr(env);                                                    \
+    return result;                                                        \
+}                                                                         \
+                                                                          \
+uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
+                                     uint32_t fdt0, uint32_t fdt1)        \
+{                                                                         \
+    uint32_t result;                                                      \
+    set_float_exception_flags(0, &env->fp_status);                        \
+    result = float32_ ## name(fdt0, fdt1, &env->fp_status);               \
+    update_fpcsr(env);                                                    \
+    return result;                                                        \
+}                                                                         \
+
+FLOAT_CALC(add)
+FLOAT_CALC(sub)
+FLOAT_CALC(mul)
+FLOAT_CALC(div)
+FLOAT_CALC(rem)
+#undef FLOAT_CALC
+
+#define FLOAT_TERNOP(name1, name2)                                        \
+uint64_t helper_float_ ## name1 ## name2 ## _d(CPUOpenRISCState *env,     \
+                                               uint64_t fdt0,             \
+                                               uint64_t fdt1)             \
+{                                                                         \
+    uint64_t result, temp, hi, lo;                                        \
+    uint32_t val1, val2;                                                  \
+    hi = env->fpmaddhi;                                                   \
+    lo = env->fpmaddlo;                                                   \
+    set_float_exception_flags(0, &env->fp_status);                        \
+    result = float64_ ## name1(fdt0, fdt1, &env->fp_status);              \
+    lo &= 0xffffffff;                                                     \
+    hi &= 0xffffffff;                                                     \
+    temp = (hi << 32) | lo;                                               \
+    result = float64_ ## name2(result, temp, &env->fp_status);            \
+    val1 = result >> 32;                                                  \
+    val2 = (uint32_t) (result & 0xffffffff);                              \
+    update_fpcsr(env);                                                    \
+    env->fpmaddlo = val2;                                                 \
+    env->fpmaddhi = val1;                                                 \
+    return 0;                                                             \
+}                                                                         \
+                                                                          \
+uint32_t helper_float_ ## name1 ## name2 ## _s(CPUOpenRISCState *env,     \
+                                            uint32_t fdt0, uint32_t fdt1) \
+{                                                                         \
+    uint64_t result, temp, hi, lo;                                        \
+    uint32_t val1, val2;                                                  \
+    hi = env->fpmaddhi;                                                   \
+    lo = env->fpmaddlo;                                                   \
+    set_float_exception_flags(0, &env->fp_status);                        \
+    result = float64_ ## name1(fdt0, fdt1, &env->fp_status);              \
+    temp = (hi << 32) | lo;                                               \
+    result = float64_ ## name2(result, temp, &env->fp_status);            \
+    val1 = result >> 32;                                                  \
+    val2 = (uint32_t) (result & 0xffffffff);                              \
+    update_fpcsr(env);                                                    \
+    env->fpmaddlo = val2;                                                 \
+    env->fpmaddhi = val1;                                                 \
+    return 0;                                                             \
+}
+
+FLOAT_TERNOP(mul, add)
+#undef FLOAT_TERNOP
+
+
+#define FLOAT_CMP(name)                                                   \
+uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
+                                     uint64_t fdt0, uint64_t fdt1)        \
+{                                                                         \
+   int res;                                                               \
+   set_float_exception_flags(0, &env->fp_status);                         \
+   res = float64_ ## name(fdt0, fdt1, &env->fp_status);                   \
+   update_fpcsr(env);                                                     \
+   return res;                                                            \
+}                                                                         \
+                                                                          \
+uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
+                                             uint32_t fdt0, uint32_t fdt1)\
+{                                                                         \
+    int res;                                                              \
+    set_float_exception_flags(0, &env->fp_status);                        \
+    res = float32_ ## name(fdt0, fdt1, &env->fp_status);                  \
+    update_fpcsr(env);                                                    \
+    return res;                                                           \
+}
+
+FLOAT_CMP(le)
+FLOAT_CMP(eq)
+FLOAT_CMP(lt)
+#undef FLOAT_CMP
+
+
+#define FLOAT_CMPNE(name)                                                 \
+uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
+                                     uint64_t fdt0, uint64_t fdt1)        \
+{                                                                         \
+   int res;                                                               \
+   set_float_exception_flags(0, &env->fp_status);                         \
+   res = !float64_eq_quiet(fdt0, fdt1, &env->fp_status);                  \
+   update_fpcsr(env);                                                     \
+   return res;                                                            \
+}                                                                         \
+                                                                          \
+uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
+                                     uint32_t fdt0, uint32_t fdt1)        \
+{                                                                         \
+    int res;                                                              \
+    set_float_exception_flags(0, &env->fp_status);                        \
+    res = !float32_eq_quiet(fdt0, fdt1, &env->fp_status);                 \
+    update_fpcsr(env);                                                    \
+    return res;                                                           \
+}
+
+FLOAT_CMPNE(ne)
+#undef FLOAT_CMPNE
+
+#define FLOAT_CMPGT(name)                                                 \
+uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
+                                     uint64_t fdt0, uint64_t fdt1)        \
+{                                                                         \
+   int res;                                                               \
+   set_float_exception_flags(0, &env->fp_status);                         \
+   res = !float64_le(fdt0, fdt1, &env->fp_status);                        \
+   update_fpcsr(env);                                                     \
+   return res;                                                            \
+}                                                                         \
+                                                                          \
+uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
+                                     uint32_t fdt0, uint32_t fdt1)        \
+{                                                                         \
+    int res;                                                              \
+    set_float_exception_flags(0, &env->fp_status);                        \
+    res = !float32_le(fdt0, fdt1, &env->fp_status);                       \
+    update_fpcsr(env);                                                    \
+    return res;                                                           \
+}
+FLOAT_CMPGT(gt)
+#undef FLOAT_CMPGT
+
+#define FLOAT_CMPGE(name)                                                 \
+uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
+                                     uint64_t fdt0, uint64_t fdt1)        \
+{                                                                         \
+   int res;                                                               \
+   set_float_exception_flags(0, &env->fp_status);                         \
+   res = !float64_lt(fdt0, fdt1, &env->fp_status);                        \
+   update_fpcsr(env);                                                     \
+   return res;                                                            \
+}                                                                         \
+                                                                          \
+uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
+                                     uint32_t fdt0, uint32_t fdt1)        \
+{                                                                         \
+    int res;                                                              \
+    set_float_exception_flags(0, &env->fp_status);                        \
+    res = !float32_lt(fdt0, fdt1, &env->fp_status);                       \
+    update_fpcsr(env);                                                    \
+    return res;                                                           \
+}
+
+FLOAT_CMPGE(ge)
+#undef FLOAT_CMPGE
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index c772951..6eb259a 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -22,6 +22,39 @@
 /* exception */
 DEF_HELPER_FLAGS_2(exception, 0, void, env, i32)
 
+/* float */
+DEF_HELPER_FLAGS_2(itofd, 0, i64, env, i64)
+DEF_HELPER_FLAGS_2(itofs, 0, i32, env, i32)
+DEF_HELPER_FLAGS_2(ftoid, 0, i64, env, i64)
+DEF_HELPER_FLAGS_2(ftois, 0, i32, env, i32)
+
+#define FOP_MADD(op)                                             \
+DEF_HELPER_FLAGS_3(float_ ## op ## _s, 0, i32, env, i32, i32)    \
+DEF_HELPER_FLAGS_3(float_ ## op ## _d, 0, i64, env, i64, i64)
+FOP_MADD(muladd)
+#undef FOP_MADD
+
+#define FOP_CALC(op)                                            \
+DEF_HELPER_FLAGS_3(float_ ## op ## _s, 0, i32, env, i32, i32)    \
+DEF_HELPER_FLAGS_3(float_ ## op ## _d, 0, i64, env, i64, i64)
+FOP_CALC(add)
+FOP_CALC(sub)
+FOP_CALC(mul)
+FOP_CALC(div)
+FOP_CALC(rem)
+#undef FOP_CALC
+
+#define FOP_CMP(op)                                              \
+DEF_HELPER_FLAGS_3(float_ ## op ## _s, 0, i32, env, i32, i32)    \
+DEF_HELPER_FLAGS_3(float_ ## op ## _d, 0, i64, env, i64, i64)
+FOP_CMP(eq)
+FOP_CMP(lt)
+FOP_CMP(le)
+FOP_CMP(ne)
+FOP_CMP(gt)
+FOP_CMP(ge)
+#undef FOP_CMP
+
 /* int */
 DEF_HELPER_FLAGS_1(ff1, 0, tl, tl)
 DEF_HELPER_FLAGS_1(fl1, 0, tl, tl)
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 08/16] target-or32: Add instruction tanslation
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
                   ` (6 preceding siblings ...)
  2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 07/16] target-or32: Add float " Jia Liu
@ 2012-06-21  2:58 ` Jia Liu
  2012-06-21 10:24   ` Max Filippov
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 09/16] target-or32: Add PIC support Jia Liu
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:58 UTC (permalink / raw)
  To: qemu-devel

Add OpenRISC instruction tanslation routines.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 target-openrisc/translate.c | 1676 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1676 insertions(+)

diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 1d87d76..300236f 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -26,6 +26,10 @@
 #include "qemu-log.h"
 #include "config.h"
 
+#include "helper.h"
+#define GEN_HELPER 1
+#include "helper.h"
+
 #define OPENRISC_DISAS
 
 #ifdef OPENRISC_DISAS
@@ -34,14 +38,1686 @@
 #  define LOG_DIS(...) do { } while (0)
 #endif
 
+typedef struct DisasContext {
+    CPUOpenRISCState *env;
+    TranslationBlock *tb;
+    target_ulong pc, ppc, npc;
+    uint32_t tb_flags, synced_flags, flags;
+    uint32_t is_jmp;
+    uint32_t mem_idx;
+    int singlestep_enabled;
+    uint32_t delayed_branch;
+} DisasContext;
+
+static TCGv_ptr cpu_env;
+static TCGv cpu_sr;
+static TCGv cpu_R[32];
+static TCGv cpu_pc;
+static TCGv jmp_pc;            /* l.jr/l.jalr temp pc */
+static TCGv cpu_npc;
+static TCGv cpu_ppc;
+static TCGv_i32 env_btaken;    /* bf/bnf , F flag taken */
+static TCGv_i32 fpcsr;
+static TCGv machi, maclo;
+static TCGv fpmaddhi, fpmaddlo;
+static TCGv_i32 env_flags;
+#include "gen-icount.h"
+
 void openrisc_translate_init(void)
 {
+    static const char * const regnames[] = {
+        "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+        "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+        "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+        "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+    };
+    int i;
+
+    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    cpu_sr = tcg_global_mem_new(TCG_AREG0,
+                                offsetof(CPUOpenRISCState, sr), "sr");
+    env_flags = tcg_global_mem_new_i32(TCG_AREG0,
+                                       offsetof(CPUOpenRISCState, flags),
+                                       "flags");
+    cpu_pc = tcg_global_mem_new(TCG_AREG0,
+                                offsetof(CPUOpenRISCState, pc), "pc");
+    cpu_npc = tcg_global_mem_new(TCG_AREG0,
+                                 offsetof(CPUOpenRISCState, npc), "npc");
+    cpu_ppc = tcg_global_mem_new(TCG_AREG0,
+                                 offsetof(CPUOpenRISCState, ppc), "ppc");
+    jmp_pc = tcg_global_mem_new(TCG_AREG0,
+                                offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc");
+    env_btaken = tcg_global_mem_new_i32(TCG_AREG0,
+                                        offsetof(CPUOpenRISCState, btaken),
+                                        "btaken");
+    fpcsr = tcg_global_mem_new_i32(TCG_AREG0,
+                                   offsetof(CPUOpenRISCState, fpcsr),
+                                   "fpcsr");
+    machi = tcg_global_mem_new(TCG_AREG0,
+                               offsetof(CPUOpenRISCState, machi),
+                               "machi");
+    maclo = tcg_global_mem_new(TCG_AREG0,
+                               offsetof(CPUOpenRISCState, maclo),
+                               "maclo");
+    fpmaddhi = tcg_global_mem_new(TCG_AREG0,
+                                  offsetof(CPUOpenRISCState, fpmaddhi),
+                                  "fpmaddhi");
+    fpmaddlo = tcg_global_mem_new(TCG_AREG0,
+                                  offsetof(CPUOpenRISCState, fpmaddlo),
+                                  "fpmaddlo");
+    for (i = 0; i < 32; i++) {
+        cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
+                                      offsetof(CPUOpenRISCState, gpr[i]),
+                                      regnames[i]);
+    }
+#define GEN_HELPER 2
+#include "helper.h"
+}
+
+/* Writeback SR_F transaltion-space to execution-space.  */
+static inline void wb_SR_F(void)
+{
+    int label;
+
+    label = gen_new_label();
+    tcg_gen_andi_tl(cpu_sr, cpu_sr, ~SR_F);
+    tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, label);
+    tcg_gen_ori_tl(cpu_sr, cpu_sr, SR_F);
+    gen_set_label(label);
+}
+
+static inline int zero_extend(unsigned int val, int width)
+{
+    return val & ((1 << width) - 1);
+}
+
+static inline int sign_extend(unsigned int val, int width)
+{
+    int sval;
+
+    /* LSL */
+    val <<= TARGET_LONG_BITS - width;
+    sval = val;
+    /* ASR.  */
+    sval >>= TARGET_LONG_BITS - width;
+    return sval;
+}
+
+static inline void gen_sync_flags(DisasContext *dc)
+{
+    /* Sync the tb dependent flag between translate and runtime.  */
+    if (dc->tb_flags != dc->synced_flags) {
+        tcg_gen_movi_tl(env_flags, dc->tb_flags);
+        dc->synced_flags = dc->tb_flags;
+    }
+}
+
+static void gen_exception(DisasContext *dc, unsigned int excp)
+{
+    TCGv_i32 tmp = tcg_const_i32(excp);
+    gen_helper_exception(cpu_env, tmp);
+    tcg_temp_free_i32(tmp);
+}
+
+static void gen_illegal_exception(DisasContext *dc)
+{
+    tcg_gen_movi_tl(cpu_pc, dc->pc);
+    gen_exception(dc, EXCP_ILLEGAL);
+    dc->is_jmp = DISAS_UPDATE;
+}
+
+#ifdef TARGET_OPENRISC64
+static void check_ob64s(DisasContext *dc)
+{
+    if (!(dc->flags & CPUCFGR_OB64S)) {
+        gen_illegal_exception(dc);
+    }
+}
+
+static void check_of64s(DisasContext *dc)
+{
+    if (!(dc->flags & CPUCFGR_OF64S)) {
+        gen_illegal_exception(dc);
+    }
+}
+
+/* not used yet, open it when we need or64.  */
+/*static void check_ov64s(DisasContext *dc)
+{
+    if (!(dc->flags & CPUCFGR_OV64S)) {
+        gen_illegal_exception(dc);
+    }
+}*/
+#endif
+
+static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
+{
+    TranslationBlock *tb;
+    tb = dc->tb;
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
+                                       likely(!dc->singlestep_enabled)) {
+        tcg_gen_movi_tl(cpu_pc, dest);
+        tcg_gen_goto_tb(n);
+        tcg_gen_exit_tb((tcg_target_long)tb + n);
+    } else {
+        tcg_gen_movi_tl(cpu_pc, dest);
+        if (dc->singlestep_enabled) {
+            gen_exception(dc, EXCP_DEBUG);
+        }
+        tcg_gen_exit_tb(0);
+    }
+}
+
+static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0)
+{
+    target_ulong tmp_pc;
+    int lab = gen_new_label();
+    TCGv sr_f = tcg_temp_new();
+    /* N26, 26bits imm */
+    tmp_pc = sign_extend((imm<<2), 26) + dc->pc;
+    tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);
+
+    if (op0 == 0x00) {    /*l.j*/
+        tcg_gen_movi_tl(jmp_pc, tmp_pc);
+    } else if (op0 == 0x01) {    /*l.jal*/
+        tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8));
+        tcg_gen_movi_tl(jmp_pc, tmp_pc);
+    } else if (op0 == 0x03) {    /*l.bnf*/
+        tcg_gen_movi_tl(jmp_pc, dc->pc+8);
+        tcg_gen_brcondi_i32(TCG_COND_EQ, sr_f, SR_F, lab);
+        tcg_gen_movi_tl(jmp_pc, tmp_pc);
+        gen_set_label(lab);
+    } else if (op0 == 0x04) {    /*l.bf*/
+        tcg_gen_movi_tl(jmp_pc, dc->pc+8);
+        tcg_gen_brcondi_i32(TCG_COND_NE, sr_f, SR_F, lab);
+        tcg_gen_movi_tl(jmp_pc, tmp_pc);
+        gen_set_label(lab);
+    } else if (op0 == 0x11) {    /*l.jr*/
+        tcg_gen_mov_tl(jmp_pc, cpu_R[reg]);
+    } else if (op0 == 0x12) {    /*l.jalr*/
+        tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8));
+        tcg_gen_mov_tl(jmp_pc, cpu_R[reg]);
+    } else {
+        gen_illegal_exception(dc);
+    }
+
+    tcg_temp_free(sr_f);
+    dc->delayed_branch = 2;
+    dc->tb_flags |= D_FLAG;
+    gen_sync_flags(dc);
+}
+
+static inline uint32_t field(uint32_t val, int start, int length)
+{
+    val >>= start;
+    val &= ~(~0 << length);
+    return val;
+}
+
+static void dec_calc(DisasContext *dc, CPUOpenRISCState *env, uint32_t insn)
+{
+    uint32_t op0, op1, op2;
+    uint32_t ra, rb, rd;
+    op0 = field(insn, 0, 4);
+    op1 = field(insn, 8, 2);
+    op2 = field(insn, 6, 2);
+    ra = field(insn, 16, 5);
+    rb = field(insn, 11, 5);
+    rd = field(insn, 21, 5);
+
+    switch (op0) {
+    case 0x0000:
+        switch (op1) {
+        case 0x00:     /*l.add*/
+            LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);
+            {
+                int lab = gen_new_label();
+                TCGv_i64 ta = tcg_temp_new_i64();
+                TCGv_i64 tb = tcg_temp_new_i64();
+                TCGv_i64 td = tcg_temp_local_new_i64();
+                TCGv_i32 res = tcg_temp_local_new_i32();
+                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
+                tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
+                tcg_gen_extu_i32_i64(tb, cpu_R[rb]);
+                tcg_gen_add_i64(td, ta, tb);
+                tcg_gen_trunc_i64_i32(res, td);
+                tcg_gen_shri_i64(td, td, 31);
+                tcg_gen_andi_i64(td, td, 0x3);
+                /* Jump to lab when no overflow.  */
+                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
+                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
+                tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
+                tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
+                tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
+                gen_exception(dc, EXCP_RANGE);
+                gen_set_label(lab);
+                tcg_gen_mov_i32(cpu_R[rd], res);
+                tcg_temp_free_i64(ta);
+                tcg_temp_free_i64(tb);
+                tcg_temp_free_i64(td);
+                tcg_temp_free_i32(res);
+                tcg_temp_free_i32(sr_ove);
+            }
+            break;
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x0001:    /*l.addc*/
+        switch (op1) {
+        case 0x00:
+            LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb);
+            {
+                int lab = gen_new_label();
+                TCGv_i64 ta = tcg_temp_new_i64();
+                TCGv_i64 tb = tcg_temp_new_i64();
+                TCGv_i64 tcy = tcg_temp_local_new_i64();
+                TCGv_i64 td = tcg_temp_local_new_i64();
+                TCGv_i32 res = tcg_temp_local_new_i32();
+                TCGv_i32 sr_cy = tcg_temp_local_new_i32();
+                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
+                tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
+                tcg_gen_extu_i32_i64(tb, cpu_R[rb]);
+                tcg_gen_andi_i32(sr_cy, cpu_sr, SR_CY);
+                tcg_gen_extu_i32_i64(tcy, sr_cy);
+                tcg_gen_shri_i64(tcy, tcy, 10);
+                tcg_gen_add_i64(td, ta, tb);
+                tcg_gen_add_i64(td, td, tcy);
+                tcg_gen_trunc_i64_i32(res, td);
+                tcg_gen_shri_i64(td, td, 32);
+                tcg_gen_andi_i64(td, td, 0x3);
+                /* Jump to lab when no overflow.  */
+                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
+                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
+                tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
+                tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
+                tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
+                gen_exception(dc, EXCP_RANGE);
+                gen_set_label(lab);
+                tcg_gen_mov_i32(cpu_R[rd], res);
+                tcg_temp_free_i64(ta);
+                tcg_temp_free_i64(tb);
+                tcg_temp_free_i64(tcy);
+                tcg_temp_free_i64(td);
+                tcg_temp_free_i32(res);
+                tcg_temp_free_i32(sr_cy);
+                tcg_temp_free_i32(sr_ove);
+            }
+            break;
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x0002:    /*l.sub*/
+        switch (op1) {
+        case 0x00:
+            LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb);
+            {
+                int lab = gen_new_label();
+                TCGv_i64 ta = tcg_temp_new_i64();
+                TCGv_i64 tb = tcg_temp_new_i64();
+                TCGv_i64 td = tcg_temp_local_new_i64();
+                TCGv_i32 res = tcg_temp_local_new_i32();
+                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
+
+                tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
+                tcg_gen_extu_i32_i64(tb, cpu_R[rb]);
+                tcg_gen_sub_i64(td, ta, tb);
+                tcg_gen_trunc_i64_i32(res, td);
+                tcg_gen_shri_i64(td, td, 31);
+                tcg_gen_andi_i64(td, td, 0x3);
+                /* Jump to lab when no overflow.  */
+                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
+                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
+                tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
+                tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
+                tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
+                gen_exception(dc, EXCP_RANGE);
+                gen_set_label(lab);
+                tcg_gen_mov_i32(cpu_R[rd], res);
+                tcg_temp_free_i64(ta);
+                tcg_temp_free_i64(tb);
+                tcg_temp_free_i64(td);
+                tcg_temp_free_i32(res);
+                tcg_temp_free_i32(sr_ove);
+            }
+            break;
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x0003:   /*l.and*/
+        switch (op1) {
+        case 0x00:
+            LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb);
+            tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+            break;
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x0004:   /*l.or*/
+        switch (op1) {
+        case 0x00:
+            LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb);
+            tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+            break;
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x0005:
+        switch (op1) {
+        case 0x00:   /*l.xor*/
+            LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb);
+            tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+            break;
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x0006:
+        switch (op1) {
+        case 0x03:   /*l.mul*/
+            LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);
+            if (ra != 0 && rb != 0) {
+                gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+            } else {
+                tcg_gen_movi_tl(cpu_R[rd], 0x0);
+            }
+            break;
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x0009:
+        switch (op1) {
+        case 0x03:   /*l.div*/
+            LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
+            {
+                int lab0 = gen_new_label();
+                int lab1 = gen_new_label();
+                int lab2 = gen_new_label();
+                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
+                if (rb == 0) {
+                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
+                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);
+                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
+                    gen_exception(dc, EXCP_RANGE);
+                    gen_set_label(lab0);
+                } else {
+                    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[rb],
+                                       0x00000000, lab1);
+                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[ra],
+                                       0xffffffff, lab2);
+                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],
+                                       0x80000000, lab2);
+                    gen_set_label(lab1);
+                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
+                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
+                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab2);
+                    gen_exception(dc, EXCP_RANGE);
+                    gen_set_label(lab2);
+                    tcg_gen_div_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+                }
+                tcg_temp_free_i32(sr_ove);
+            }
+            break;
+
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x000a:
+        switch (op1) {
+        case 0x03:   /*l.divu*/
+            LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
+            {
+                int lab0 = gen_new_label();
+                int lab1 = gen_new_label();
+                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
+                if (rb == 0) {
+                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
+                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
+                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);
+                    gen_exception(dc, EXCP_RANGE);
+                    gen_set_label(lab0);
+                } else {
+                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],
+                                       0x00000000, lab1);
+                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
+                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
+                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab1);
+                    gen_exception(dc, EXCP_RANGE);
+                    gen_set_label(lab1);
+                    tcg_gen_divu_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+                }
+                tcg_temp_free_i32(sr_ove);
+            }
+            break;
+
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x000b:
+        switch (op1) {
+        case 0x03:   /*l.mulu*/
+            LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
+            if (rb != 0 && ra != 0) {
+                TCGv_i64 result = tcg_temp_local_new_i64();
+                TCGv_i64 tra = tcg_temp_local_new_i64();
+                TCGv_i64 trb = tcg_temp_local_new_i64();
+                TCGv_i64 high = tcg_temp_new_i64();
+                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
+                int lab = gen_new_label();
+                /* Calculate the each result.  */
+                tcg_gen_extu_i32_i64(tra, cpu_R[ra]);
+                tcg_gen_extu_i32_i64(trb, cpu_R[rb]);
+                tcg_gen_mul_i64(result, tra, trb);
+                tcg_temp_free_i64(tra);
+                tcg_temp_free_i64(trb);
+                tcg_gen_shri_i64(high, result, TARGET_LONG_BITS);
+                /* Overflow or not.  */
+                tcg_gen_brcondi_i64(TCG_COND_EQ, high, 0x00000000, lab);
+                tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
+                tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
+                tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab);
+                gen_exception(dc, EXCP_RANGE);
+                gen_set_label(lab);
+                tcg_temp_free_i64(high);
+                tcg_gen_trunc_i64_tl(cpu_R[rd], result);
+                tcg_temp_free_i64(result);
+                tcg_temp_free_i32(sr_ove);
+            } else {
+                tcg_gen_movi_tl(cpu_R[rd], 0);
+            }
+            break;
+
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x000e:
+        switch (op1) {
+        case 0x00:   /*l.cmov*/
+            LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
+            {
+                int lab = gen_new_label();
+                TCGv res = tcg_temp_new();
+                TCGv sr_f = tcg_temp_new();
+                tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);
+                tcg_gen_mov_tl(res, cpu_R[rb]);
+                tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab);
+                tcg_gen_mov_tl(res, cpu_R[ra]);
+                gen_set_label(lab);
+                tcg_gen_mov_tl(cpu_R[rd], res);
+                tcg_temp_free(sr_f);
+                tcg_temp_free(res);
+            }
+            break;
+
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x000f:
+        switch (op1) {
+        case 0x00:   /*l.ff1*/
+            LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb);
+            gen_helper_ff1(cpu_R[rd], cpu_R[ra]);
+            break;
+        case 0x01:   /*l.fl1*/
+            LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb);
+            gen_helper_fl1(cpu_R[rd], cpu_R[ra]);
+            break;
+
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x0008:
+        switch (op1) {
+        case 0x00:
+            switch (op2) {
+            case 0x00:   /*l.sll*/
+                LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb);
+                tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+                break;
+            case 0x01:   /*l.srl*/
+                LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb);
+                tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+                break;
+            case 0x02:   /*l.sra*/
+                LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb);
+                tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+                break;
+            case 0x03:   /*l.ror*/
+                LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb);
+                tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+                break;
+
+            default:
+                gen_illegal_exception(dc);
+                break;
+            }
+            break;
+
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x000c:
+        switch (op1) {
+        case 0x00:
+            switch (op2) {
+            case 0x00:   /*l.exths*/
+                LOG_DIS("l.exths r%d, r%d\n", rd, ra);
+                tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);
+                break;
+            case 0x01:   /*l.extbs*/
+                LOG_DIS("l.extbs r%d, r%d\n", rd, ra);
+                tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]);
+                break;
+            case 0x02:   /*l.exthz*/
+                LOG_DIS("l.exthz r%d, r%d\n", rd, ra);
+                tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]);
+                break;
+            case 0x03:   /*l.extbz*/
+                LOG_DIS("l.extbz r%d, r%d\n", rd, ra);
+                tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]);
+                break;
+
+            default:
+                gen_illegal_exception(dc);
+                break;
+            }
+            break;
+
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x000d:
+        switch (op1) {
+        case 0x00:
+            switch (op2) {
+            case 0x00:   /*l.extws*/
+                LOG_DIS("l.extws r%d, r%d\n", rd, ra);
+                tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]);
+                break;
+            case 0x01:    /*l.extwz*/
+                LOG_DIS("l.extwz r%d, r%d\n", rd, ra);
+                tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]);
+                break;
+
+            default:
+                gen_illegal_exception(dc);
+                break;
+            }
+            break;
+
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    default:
+        gen_illegal_exception(dc);
+        break;
+    }
+}
+
+static void dec_misc(DisasContext *dc, CPUOpenRISCState *env, uint32_t insn)
+{
+    uint32_t op0, op1;
+    uint32_t ra, rb, rd;
+    uint32_t /*L6, K5, */I16, I5, I11, N26, tmp;
+    op0 = field(insn, 26, 6);
+    op1 = field(insn, 24, 2);
+    ra = field(insn, 16, 5);
+    rb = field(insn, 11, 5);
+    rd = field(insn, 21, 5);
+    /*L6 = field(insn, 5, 6);
+    K5 = field(insn, 0, 5);*/
+    I16 = field(insn, 0, 16);
+    I5 = field(insn, 21, 5);
+    I11 = field(insn, 0, 11);
+    N26 = field(insn, 0, 26);
+    tmp = (I5<<11) + I11;
+
+    switch (op0) {
+    case 0x00:   /*l.j*/
+        LOG_DIS("l.j %d\n", N26);
+    case 0x01:   /*l.jal*/
+        LOG_DIS("l.jal %d\n", N26);
+    case 0x03:   /*l.bnf*/
+        LOG_DIS("l.bnf %d\n", N26);
+    case 0x04:   /*l.bf*/
+        LOG_DIS("l.bf %d\n", N26);
+
+        gen_jump(dc, N26, 0, op0);
+        break;
+
+    case 0x05:
+        switch (op1) {
+        case 0x01:   /*l.nop*/
+            LOG_DIS("l.nop %d\n", I16);
+            break;
+
+        default:
+            gen_illegal_exception(dc);
+            break;
+        }
+        break;
+
+    case 0x11:    /*l.jr*/
+        LOG_DIS("l.jr r%d\n", rb);
+    case 0x12:    /*l.jalr*/
+        LOG_DIS("l.jalr r%d\n", rb);
+
+        gen_jump(dc, 0, rb, op0);
+        break;
+
+    case 0x13:    /*l.maci*/
+        LOG_DIS("l.maci %d, r%d, %d\n", I5, ra, I11);
+        {
+            TCGv_i64 t1 = tcg_temp_new_i64();
+            TCGv_i64 t2 = tcg_temp_new_i64();
+            TCGv_i32 dst = tcg_temp_new_i32();
+            TCGv ttmp = tcg_const_tl(tmp);
+            tcg_gen_mul_tl(dst, cpu_R[ra], ttmp);
+            tcg_gen_ext_i32_i64(t1, dst);
+            tcg_gen_concat_i32_i64(t2, maclo, machi);
+            tcg_gen_add_i64(t2, t2, t1);
+            tcg_gen_trunc_i64_i32(maclo, t2);
+            tcg_gen_shri_i64(t2, t2, 32);
+            tcg_gen_trunc_i64_i32(machi, t2);
+            tcg_temp_free_i32(dst);
+            tcg_temp_free(ttmp);
+            tcg_temp_free_i64(t1);
+            tcg_temp_free_i64(t2);
+        }
+        break;
+
+    case 0x09:    /*l.rfe*/
+        LOG_DIS("l.rfe\n");
+        {
+            gen_helper_rfe(cpu_env);
+            dc->is_jmp = DISAS_UPDATE;
+        }
+        break;
+
+    case 0x1c:    /*l.cust1*/
+        LOG_DIS("l.cust1\n");
+        break;
+
+    case 0x1d:    /*l.cust2*/
+        LOG_DIS("l.cust2\n");
+        break;
+
+    case 0x1e:    /*l.cust3*/
+        LOG_DIS("l.cust3\n");
+        break;
+
+    case 0x1f:    /*l.cust4*/
+        LOG_DIS("l.cust4\n");
+        break;
+
+    case 0x3c:   /*l.cust5*/
+        /*LOG_DIS("l.cust5 r%d, r%d, r%d, %d, %d\n", rd, ra, rb, L6, K5);*/
+        break;
+
+    case 0x3d:   /*l.cust6*/
+        LOG_DIS("l.cust6\n");
+        break;
+
+    case 0x3e:   /*l.cust7*/
+        LOG_DIS("l.cust7\n");
+        break;
+
+    case 0x3f:   /*l.cust8*/
+        LOG_DIS("l.cust8\n");
+        break;
+
+    case 0x20:   /*l.ld*/
+        LOG_DIS("l.ld r%d, r%d, %d\n", rd, ra, I16);
+        {
+#ifdef TARGET_OPENRISC64
+            check_ob64s(dc);
+            TCGv_i64 t0 = tcg_temp_new_i64();
+            tcg_gen_addi_i64(t0, cpu_R[ra], sign_extend(I16, 16));
+            tcg_gen_qemu_ld64(cpu_R[rd], t0, dc->mem_idx);
+            tcg_temp_free_i64(t0);
+#endif
+        }
+        break;
+
+    case 0x21:   /*l.lwz*/
+        LOG_DIS("l.lwz r%d, r%d, %d\n", rd, ra, I16);
+        {
+            TCGv t0 = tcg_temp_new();
+            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
+            tcg_gen_qemu_ld32u(cpu_R[rd], t0, dc->mem_idx);
+            tcg_temp_free(t0);
+        }
+        break;
+
+    case 0x22:   /*l.lws*/
+        LOG_DIS("l.lws r%d, r%d, %d\n", rd, ra, I16);
+        {
+            TCGv t0 = tcg_temp_new();
+            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
+            tcg_gen_qemu_ld32s(cpu_R[rd], t0, dc->mem_idx);
+            tcg_temp_free(t0);
+        }
+        break;
+
+    case 0x23:   /*l.lbz*/
+        LOG_DIS("l.lbz r%d, r%d, %d\n", rd, ra, I16);
+        {
+            TCGv t0 = tcg_temp_new();
+            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
+            tcg_gen_qemu_ld8u(cpu_R[rd], t0, dc->mem_idx);
+            tcg_temp_free(t0);
+        }
+        break;
+
+    case 0x24:   /*l.lbs*/
+        LOG_DIS("l.lbs r%d, r%d, %d\n", rd, ra, I16);
+        {
+            TCGv t0 = tcg_temp_new();
+            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
+            tcg_gen_qemu_ld8s(cpu_R[rd], t0, dc->mem_idx);
+            tcg_temp_free(t0);
+        }
+        break;
+
+    case 0x25:   /*l.lhz*/
+        LOG_DIS("l.lhz r%d, r%d, %d\n", rd, ra, I16);
+        {
+            TCGv t0 = tcg_temp_new();
+            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
+            tcg_gen_qemu_ld16u(cpu_R[rd], t0, dc->mem_idx);
+            tcg_temp_free(t0);
+        }
+        break;
+
+    case 0x26:   /*l.lhs*/
+        LOG_DIS("l.lhs r%d, r%d, %d\n", rd, ra, I16);
+        {
+            TCGv t0 = tcg_temp_new();
+            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
+            tcg_gen_qemu_ld16s(cpu_R[rd], t0, dc->mem_idx);
+            tcg_temp_free(t0);
+        }
+        break;
+
+    case 0x27:   /*l.addi*/
+        LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16);
+        {
+            int lab = gen_new_label();
+            TCGv_i64 ta = tcg_temp_new_i64();
+            TCGv_i64 td = tcg_temp_local_new_i64();
+            TCGv_i32 res = tcg_temp_local_new_i32();
+            TCGv_i32 sr_ove = tcg_temp_local_new_i32();
+            tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
+            tcg_gen_addi_i64(td, ta, sign_extend(I16, 16));
+            tcg_gen_trunc_i64_i32(res, td);
+            tcg_gen_shri_i64(td, td, 32);
+            tcg_gen_andi_i64(td, td, 0x3);
+            /* Jump to lab when no overflow.  */
+            tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
+            tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
+            tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
+            tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
+            tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
+            gen_exception(dc, EXCP_RANGE);
+            gen_set_label(lab);
+            tcg_gen_mov_i32(cpu_R[rd], res);
+            tcg_temp_free_i64(ta);
+            tcg_temp_free_i64(td);
+            tcg_temp_free_i32(res);
+            tcg_temp_free_i32(sr_ove);
+        }
+        break;
+
+    case 0x28:   /*l.addic*/
+        LOG_DIS("l.addic r%d, r%d, %d\n", rd, ra, I16);
+        {
+            int lab = gen_new_label();
+            TCGv_i64 ta = tcg_temp_new_i64();
+            TCGv_i64 td = tcg_temp_local_new_i64();
+            TCGv_i64 tcy = tcg_temp_local_new_i64();
+            TCGv_i32 res = tcg_temp_local_new_i32();
+            TCGv_i32 sr_cy = tcg_temp_local_new_i32();
+            TCGv_i32 sr_ove = tcg_temp_local_new_i32();
+            tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
+            tcg_gen_andi_i32(sr_cy, cpu_sr, SR_CY);
+            tcg_gen_shri_i32(sr_cy, sr_cy, 10);
+            tcg_gen_extu_i32_i64(tcy, sr_cy);
+            tcg_gen_addi_i64(td, ta, sign_extend(I16, 16));
+            tcg_gen_add_i64(td, td, tcy);
+            tcg_gen_trunc_i64_i32(res, td);
+            tcg_gen_shri_i64(td, td, 32);
+            tcg_gen_andi_i64(td, td, 0x3);
+            /* Jump to lab when no overflow.  */
+            tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
+            tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
+            tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
+            tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
+            tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
+            gen_exception(dc, EXCP_RANGE);
+            gen_set_label(lab);
+            tcg_gen_mov_i32(cpu_R[rd], res);
+            tcg_temp_free_i64(ta);
+            tcg_temp_free_i64(td);
+            tcg_temp_free_i64(tcy);
+            tcg_temp_free_i32(res);
+            tcg_temp_free_i32(sr_cy);
+            tcg_temp_free_i32(sr_ove);
+        }
+        break;
+
+    case 0x29:   /*l.andi*/
+        LOG_DIS("l.andi r%d, r%d, %d\n", rd, ra, I16);
+        tcg_gen_andi_tl(cpu_R[rd], cpu_R[ra], zero_extend(I16, 16));
+        break;
+
+    case 0x2a:   /*l.ori*/
+        LOG_DIS("l.ori r%d, r%d, %d\n", rd, ra, I16);
+        tcg_gen_ori_tl(cpu_R[rd], cpu_R[ra], zero_extend(I16, 16));
+        break;
+
+    case 0x2b:   /*l.xori*/
+        LOG_DIS("l.xori r%d, r%d, %d\n", rd, ra, I16);
+        tcg_gen_xori_tl(cpu_R[rd], cpu_R[ra], sign_extend(I16, 16));
+        break;
+
+    case 0x2c:   /*l.muli*/
+        LOG_DIS("l.muli r%d, r%d, %d\n", rd, ra, I16);
+        if (ra != 0 && I16 != 0) {
+            TCGv_i32 im = tcg_const_i32(I16);
+            gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], im);
+            tcg_temp_free_i32(im);
+        } else {
+            tcg_gen_movi_tl(cpu_R[rd], 0x0);
+        }
+        break;
+
+    case 0x2d:   /*l.mfspr*/
+        LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, I16);
+        break;
+
+    case 0x30:  /*l.mtspr*/
+        LOG_DIS("l.mtspr %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        break;
+
+    case 0x34:   /*l.sd*/
+        LOG_DIS("l.sd %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        {
+#ifdef TARGET_OPENRISC64
+            check_ob64s(dc);
+            TCGv_i64 t0 = tcg_temp_new_i64();
+            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16));
+            tcg_gen_qemu_st64(cpu_R[rb], t0, dc->mem_idx);
+            tcg_temp_free_i64(t0);
+#endif
+        }
+        break;
+
+    case 0x35:   /*l.sw*/
+        LOG_DIS("l.sw %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        {
+            TCGv t0 = tcg_temp_new();
+            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16));
+            tcg_gen_qemu_st32(cpu_R[rb], t0, dc->mem_idx);
+            tcg_temp_free(t0);
+        }
+        break;
+
+    case 0x36:   /*l.sb*/
+        LOG_DIS("l.sb %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        {
+            TCGv t0 = tcg_temp_new();
+            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16));
+            tcg_gen_qemu_st8(cpu_R[rb], t0, dc->mem_idx);
+            tcg_temp_free(t0);
+        }
+        break;
+
+    case 0x37:   /*l.sh*/
+        LOG_DIS("l.sh %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        {
+            TCGv t0 = tcg_temp_new();
+            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16));
+            tcg_gen_qemu_st16(cpu_R[rb], t0, dc->mem_idx);
+            tcg_temp_free(t0);
+        }
+        break;
+
+    default:
+        gen_illegal_exception(dc);
+        break;
+    }
+}
+
+static void dec_mac(DisasContext *dc, CPUOpenRISCState *env, uint32_t insn)
+{
+    uint32_t op0;
+    uint32_t ra, rb;
+    op0 = field(insn, 0, 4);
+    ra = field(insn, 16, 5);
+    rb = field(insn, 11, 5);
+
+    switch (op0) {
+    case 0x0001:   /*l.mac*/
+        LOG_DIS("l.mac r%d, r%d\n", ra, rb);
+        {
+            TCGv_i32 t0 = tcg_temp_new_i32();
+            TCGv_i64 t1 = tcg_temp_new_i64();
+            TCGv_i64 t2 = tcg_temp_new_i64();
+            tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]);
+            tcg_gen_ext_i32_i64(t1, t0);
+            tcg_gen_concat_i32_i64(t2, maclo, machi);
+            tcg_gen_add_i64(t2, t2, t1);
+            tcg_gen_trunc_i64_i32(maclo, t2);
+            tcg_gen_shri_i64(t2, t2, 32);
+            tcg_gen_trunc_i64_i32(machi, t2);
+            tcg_temp_free_i32(t0);
+            tcg_temp_free_i64(t1);
+            tcg_temp_free_i64(t2);
+        }
+        break;
+
+    case 0x0002:   /*l.msb*/
+        LOG_DIS("l.msb r%d, r%d\n", ra, rb);
+        {
+            TCGv_i32 t0 = tcg_temp_new_i32();
+            TCGv_i64 t1 = tcg_temp_new_i64();
+            TCGv_i64 t2 = tcg_temp_new_i64();
+            tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]);
+            tcg_gen_ext_i32_i64(t1, t0);
+            tcg_gen_concat_i32_i64(t2, maclo, machi);
+            tcg_gen_sub_i64(t2, t2, t1);
+            tcg_gen_trunc_i64_i32(maclo, t2);
+            tcg_gen_shri_i64(t2, t2, 32);
+            tcg_gen_trunc_i64_i32(machi, t2);
+            tcg_temp_free_i32(t0);
+            tcg_temp_free_i64(t1);
+            tcg_temp_free_i64(t2);
+        }
+        break;
+
+    default:
+        gen_illegal_exception(dc);
+        break;
+   }
+}
+
+static void dec_logic(DisasContext *dc, CPUOpenRISCState *env, uint32_t insn)
+{
+    uint32_t op0;
+    uint32_t rd, ra, L6;
+    op0 = field(insn, 6, 2);
+    rd = field(insn, 21, 5);
+    ra = field(insn, 16, 5);
+    L6 = field(insn, 0, 6);
+
+    switch (op0) {
+    case 0x00:    /*l.slli*/
+        LOG_DIS("l.slli r%d, r%d, %d\n", rd, ra, L6);
+        tcg_gen_shli_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f));
+        break;
+
+    case 0x01:    /*l.srli*/
+        LOG_DIS("l.srli r%d, r%d, %d\n", rd, ra, L6);
+        tcg_gen_shri_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f));
+        break;
+
+    case 0x02:    /*l.srai*/
+        LOG_DIS("l.srai r%d, r%d, %d\n", rd, ra, L6);
+        tcg_gen_sari_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f)); break;
+
+    case 0x03:    /*l.rori*/
+        LOG_DIS("l.rori r%d, r%d, %d\n", rd, ra, L6);
+        tcg_gen_rotri_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f));
+        break;
+
+    default:
+        gen_illegal_exception(dc);
+        break;
+    }
+}
+
+static void dec_M(DisasContext *dc, CPUOpenRISCState *env, uint32_t insn)
+{
+    uint32_t op0;
+    uint32_t rd;
+    uint32_t K16;
+    op0 = field(insn, 16, 1);
+    rd = field(insn, 21, 5);
+    K16 = field(insn, 0, 16);
+
+    switch (op0) {
+    case 0x0:    /*l.movhi*/
+        LOG_DIS("l.movhi  r%d, %d\n", rd, K16);
+        tcg_gen_movi_tl(cpu_R[rd], (K16 << 16));
+        break;
+
+    case 0x1:    /*l.macrc*/
+        LOG_DIS("l.macrc  r%d\n", rd);
+        tcg_gen_mov_tl(cpu_R[rd], maclo);
+        tcg_gen_movi_tl(maclo, 0x0);
+        tcg_gen_movi_tl(machi, 0x0);
+        break;
+
+    default:
+        gen_illegal_exception(dc);
+        break;
+    }
+}
+
+static void dec_comp(DisasContext *dc, CPUOpenRISCState *env, uint32_t insn)
+{
+    uint32_t op0;
+    uint32_t ra, rb;
+
+    op0 = field(insn, 21, 5);
+    ra = field(insn, 16, 5);
+    rb = field(insn, 11, 5);
+
+    tcg_gen_movi_i32(env_btaken, 0x0);
+    /* unsigned integers  */
+    tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]);
+    tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]);
+
+    switch (op0) {
+    case 0x0:    /*l.sfeq*/
+        LOG_DIS("l.sfeq  r%d, r%d\n", ra, rb);
+        tcg_gen_setcond_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x1:    /*l.sfne*/
+        LOG_DIS("l.sfne  r%d, r%d\n", ra, rb);
+        tcg_gen_setcond_tl(TCG_COND_NE, env_btaken, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x2:    /*l.sfgtu*/
+        LOG_DIS("l.sfgtu  r%d, r%d\n", ra, rb);
+        tcg_gen_setcond_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x3:    /*l.sfgeu*/
+        LOG_DIS("l.sfgeu  r%d, r%d\n", ra, rb);
+        tcg_gen_setcond_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x4:    /*l.sfltu*/
+        LOG_DIS("l.sfltu  r%d, r%d\n", ra, rb);
+        tcg_gen_setcond_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x5:    /*l.sfleu*/
+        LOG_DIS("l.sfleu  r%d, r%d\n", ra, rb);
+        tcg_gen_setcond_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0xa:    /*l.sfgts*/
+        LOG_DIS("l.sfgts  r%d, r%d\n", ra, rb);
+        tcg_gen_setcond_tl(TCG_COND_GT, env_btaken, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0xb:    /*l.sfges*/
+        LOG_DIS("l.sfges  r%d, r%d\n", ra, rb);
+        tcg_gen_setcond_tl(TCG_COND_GE, env_btaken, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0xc:    /*l.sflts*/
+        LOG_DIS("l.sflts  r%d, r%d\n", ra, rb);
+        tcg_gen_setcond_tl(TCG_COND_LT, env_btaken, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0xd:    /*l.sfles*/
+        LOG_DIS("l.sfles  r%d, r%d\n", ra, rb);
+        tcg_gen_setcond_tl(TCG_COND_LE, env_btaken, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    default:
+        gen_illegal_exception(dc);
+        break;
+    }
+    wb_SR_F();
+}
+
+static void dec_compi(DisasContext *dc, CPUOpenRISCState *env, uint32_t insn)
+{
+    uint32_t op0;
+    uint32_t ra, I16;
+
+    op0 = field(insn, 21, 5);
+    ra = field(insn, 16, 5);
+    I16 = field(insn, 0, 16);
+
+    tcg_gen_movi_i32(env_btaken, 0x0);
+    I16 = sign_extend(I16, 16);
+
+    switch (op0) {
+    case 0x0:    /*l.sfeqi*/
+        LOG_DIS("l.sfeqi  r%d, %d\n", ra, I16);
+        tcg_gen_setcondi_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], I16);
+        break;
+
+    case 0x1:    /*l.sfnei*/
+        LOG_DIS("l.sfnei  r%d, %d\n", ra, I16);
+        tcg_gen_setcondi_tl(TCG_COND_NE, env_btaken, cpu_R[ra], I16);
+        break;
+
+    case 0x2:    /*l.sfgtui*/
+        LOG_DIS("l.sfgtui  r%d, %d\n", ra, I16);
+        tcg_gen_setcondi_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], I16);
+        break;
+
+    case 0x3:    /*l.sfgeui*/
+        LOG_DIS("l.sfgeui  r%d, %d\n", ra, I16);
+        tcg_gen_setcondi_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], I16);
+        break;
+
+    case 0x4:    /*l.sfltui*/
+        LOG_DIS("l.sfltui  r%d, %d\n", ra, I16);
+        tcg_gen_setcondi_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], I16);
+        break;
+
+    case 0x5:    /*l.sfleui*/
+        LOG_DIS("l.sfleui  r%d, %d\n", ra, I16);
+        tcg_gen_setcondi_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], I16);
+        break;
+
+    case 0xa:    /*l.sfgtsi*/
+        LOG_DIS("l.sfgtsi  r%d, %d\n", ra, I16);
+        tcg_gen_setcondi_tl(TCG_COND_GT, env_btaken, cpu_R[ra], I16);
+        break;
+
+    case 0xb:    /*l.sfgesi*/
+        LOG_DIS("l.sfgesi  r%d, %d\n", ra, I16);
+        tcg_gen_setcondi_tl(TCG_COND_GE, env_btaken, cpu_R[ra], I16);
+        break;
+
+    case 0xc:    /*l.sfltsi*/
+        LOG_DIS("l.sfltsi  r%d, %d\n", ra, I16);
+        tcg_gen_setcondi_tl(TCG_COND_LT, env_btaken, cpu_R[ra], I16);
+        break;
+
+    case 0xd:    /*l.sflesi*/
+        LOG_DIS("l.sflesi  r%d, %d\n", ra, I16);
+        tcg_gen_setcondi_tl(TCG_COND_LE, env_btaken, cpu_R[ra], I16);
+        break;
+
+    default:
+        gen_illegal_exception(dc);
+        break;
+    }
+    wb_SR_F();
+}
+
+static void dec_sys(DisasContext *dc, CPUOpenRISCState *env, uint32_t insn)
+{
+    uint32_t op0;
+    /*uint32_t K16;*/
+    op0 = field(insn, 16, 8);
+    /*K16 = field(insn, 0, 16);*/
+
+    switch (op0) {
+    case 0x000:  /*l.sys*/
+        /*LOG_DIS("l.sys %d\n", K16);*/
+        tcg_gen_movi_tl(cpu_pc, dc->pc);
+        gen_exception(dc, EXCP_SYSCALL);
+        dc->is_jmp = DISAS_UPDATE;
+        break;
+
+    case 0x100:  /*l.trap*/
+        /*LOG_DIS("l.trap %d\n", K16);*/
+        tcg_gen_movi_tl(cpu_pc, dc->pc);
+        gen_exception(dc, EXCP_TRAP);
+        break;
+
+    case 0x300:  /*l.csync*/
+        LOG_DIS("l.csync\n");
+        break;
+
+    case 0x200:  /*l.msync*/
+        LOG_DIS("l.msync\n");
+        break;
+
+    case 0x270:  /*l.psync*/
+        LOG_DIS("l.psync\n");
+        break;
+
+    default:
+        gen_illegal_exception(dc);
+        break;
+    }
+}
+
+static void dec_float(DisasContext *dc, CPUOpenRISCState *env, uint32_t insn)
+{
+    uint32_t op0;
+    uint32_t ra, rb, rd;
+    op0 = field(insn, 0, 8);
+    ra = field(insn, 16, 5);
+    rb = field(insn, 11, 5);
+    rd = field(insn, 21, 5);
+
+    switch (op0) {
+    case 0x00:    /*lf.add.s*/
+        LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb);
+        gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x01:    /*lf.sub.s*/
+        LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb);
+        gen_helper_float_sub_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+
+    case 0x02:    /*lf.mul.s*/
+        LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb);
+        if (ra != 0 && rb != 0) {
+            gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        } else {
+            tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF);
+            tcg_gen_movi_i32(cpu_R[rd], 0x0);
+        }
+        break;
+
+    case 0x03:    /*lf.div.s*/
+        LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb);
+        gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x04:    /*lf.itof.s*/
+        LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
+        gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]);
+        break;
+
+    case 0x05:    /*lf.ftoi.s*/
+        LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
+        gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]);
+        break;
+
+    case 0x06:    /*lf.rem.s*/
+        LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb);
+        gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x07:    /*lf.madd.s*/
+        LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb);
+        gen_helper_float_muladd_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x08:    /*lf.sfeq.s*/
+        LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb);
+        gen_helper_float_eq_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x09:    /*lf.sfne.s*/
+        LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb);
+        gen_helper_float_ne_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x0a:    /*lf.sfgt.s*/
+        LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb);
+        gen_helper_float_gt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x0b:    /*lf.sfge.s*/
+        LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb);
+        gen_helper_float_ge_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x0c:    /*lf.sflt.s*/
+        LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb);
+        gen_helper_float_lt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x0d:    /*lf.sfle.s*/
+        LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb);
+        gen_helper_float_le_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+#ifdef TARGET_OPENRISC64
+    case 0x10:    /*lf.add.d*/
+        LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb);
+        check_of64s(dc);
+        gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x11:    /*lf.sub.d*/
+        LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb);
+        check_of64s(dc);
+        gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x12:    /*lf.mul.d*/
+        LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb);
+        check_of64s(dc);
+        if (ra != 0 && rb != 0) {
+            gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        } else {
+            tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF);
+            tcg_gen_movi_i64(cpu_R[rd], 0x0);
+        }
+        break;
+
+    case 0x13:    /*lf.div.d*/
+        LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb);
+        check_of64s(dc);
+        gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x14:    /*lf.itof.d*/
+        LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
+        check_of64s(dc);
+        gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]);
+        break;
+
+    case 0x15:    /*lf.ftoi.d*/
+        LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
+        check_of64s(dc);
+        gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]);
+        break;
+
+    case 0x16:    /*lf.rem.d*/
+        LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb);
+        check_of64s(dc);
+        gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x17:    /*lf.madd.d*/
+        LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb);
+        check_of64s(dc);
+        gen_helper_float_muladd_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x18:    /*lf.sfeq.d*/
+        LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb);
+        check_of64s(dc);
+        gen_helper_float_eq_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x1a:    /*lf.sfgt.d*/
+        LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb);
+        check_of64s(dc);
+        gen_helper_float_gt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x1b:    /*lf.sfge.d*/
+        LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb);
+        check_of64s(dc);
+        gen_helper_float_ge_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x19:    /*lf.sfne.d*/
+        LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb);
+        check_of64s(dc);
+        gen_helper_float_ne_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x1c:    /*lf.sflt.d*/
+        LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb);
+        check_of64s(dc);
+        gen_helper_float_lt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x1d:    /*lf.sfle.d*/
+        LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb);
+        check_of64s(dc);
+        gen_helper_float_le_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        break;
+#endif
+
+    default:
+        gen_illegal_exception(dc);
+        break;
+    }
+    wb_SR_F();
+}
+
+static void disas_openrisc_insn(DisasContext *dc, CPUOpenRISCState *env)
+{
+    uint32_t op0;
+    uint32_t insn;
+    insn = cpu_ldl_code(env, dc->pc);
+    op0 = field(insn, 26, 6);
+
+    switch (op0) {
+    case 0x06:
+        dec_M(dc, env, insn);
+        break;
+
+    case 0x08:
+        dec_sys(dc, env, insn);
+        break;
+
+    case 0x2e:
+        dec_logic(dc, env, insn);
+        break;
+
+    case 0x2f:
+        dec_compi(dc, env, insn);
+        break;
+
+    case 0x31:
+        dec_mac(dc, env, insn);
+        break;
+
+    case 0x32:
+        dec_float(dc, env, insn);
+        break;
+
+    case 0x38:
+        dec_calc(dc, env, insn);
+        break;
+
+    case 0x39:
+        dec_comp(dc, env, insn);
+        break;
+
+    default:
+        dec_misc(dc, env, insn);
+        break;
+    }
+}
+
+static void check_breakpoint(CPUOpenRISCState *env, DisasContext *dc)
+{
+    CPUBreakpoint *bp;
+
+    if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
+        QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+            if (bp->pc == dc->pc) {
+                tcg_gen_movi_tl(cpu_pc, dc->pc);
+                gen_exception(dc, EXCP_DEBUG);
+                dc->is_jmp = DISAS_UPDATE;
+            }
+        }
+    }
 }
 
 static inline void gen_intermediate_code_internal(CPUOpenRISCState *env,
                                                   TranslationBlock *tb,
                                                   int search_pc)
 {
+    struct DisasContext ctx, *dc = &ctx;
+    uint16_t *gen_opc_end;
+    uint32_t pc_start;
+    int j, k;
+    uint32_t next_page_start;
+    int num_insns;
+    int max_insns;
+
+    qemu_log_try_set_file(stderr);
+
+    pc_start = tb->pc;
+    dc->env = env;
+    dc->tb = tb;
+
+    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+    dc->is_jmp = DISAS_NEXT;
+    dc->ppc = pc_start;
+    dc->pc = pc_start;
+    dc->flags = env->cpucfgr;
+    dc->mem_idx = cpu_mmu_index(env);
+    dc->synced_flags = dc->tb_flags = tb->flags;
+    dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
+    dc->singlestep_enabled = env->singlestep_enabled;
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+        qemu_log("-----------------------------------------\n");
+        log_cpu_state(env, 0);
+    }
+
+    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
+    k = -1;
+    num_insns = 0;
+    max_insns = tb->cflags & CF_COUNT_MASK;
+
+    if (max_insns == 0) {
+        max_insns = CF_COUNT_MASK;
+    }
+
+    gen_icount_start();
+
+    do {
+        check_breakpoint(env, dc);
+        if (search_pc) {
+            j = gen_opc_ptr - gen_opc_buf;
+            if (k < j) {
+                k++;
+                while (k < j) {
+                    gen_opc_instr_start[k++] = 0;
+                }
+            }
+            gen_opc_pc[k] = dc->pc;
+            gen_opc_instr_start[k] = 1;
+            gen_opc_icount[k] = num_insns;
+        }
+
+        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
+            tcg_gen_debug_insn_start(dc->pc);
+        }
+
+        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
+            gen_io_start();
+        }
+        dc->ppc = dc->pc - 4;
+        dc->npc = dc->pc + 4;
+        tcg_gen_movi_tl(cpu_ppc, dc->ppc);
+        tcg_gen_movi_tl(cpu_npc, dc->npc);
+        disas_openrisc_insn(dc, env);
+        dc->pc = dc->npc;
+        num_insns++;
+        /* delay slot */
+        if (dc->delayed_branch) {
+            dc->delayed_branch--;
+            if (!dc->delayed_branch) {
+                dc->tb_flags &= ~D_FLAG;
+                gen_sync_flags(dc);
+                tcg_gen_mov_tl(cpu_pc, jmp_pc);
+                tcg_gen_mov_tl(cpu_npc, jmp_pc);
+                tcg_gen_movi_tl(jmp_pc, 0);
+                tcg_gen_exit_tb(0);
+                dc->is_jmp = DISAS_JUMP;
+                break;
+            }
+        }
+    } while (!dc->is_jmp
+             && gen_opc_ptr < gen_opc_end
+             && !env->singlestep_enabled
+             && !singlestep
+             && (dc->pc < next_page_start)
+             && num_insns < max_insns);
+
+    if (tb->cflags & CF_LAST_IO) {
+        gen_io_end();
+    }
+    if (dc->is_jmp == DISAS_NEXT) {
+        dc->is_jmp = DISAS_UPDATE;
+        tcg_gen_movi_tl(cpu_pc, dc->pc);
+    }
+    if (unlikely(env->singlestep_enabled)) {
+        if (dc->is_jmp == DISAS_NEXT) {
+            tcg_gen_movi_tl(cpu_pc, dc->pc);
+        }
+        gen_exception(dc, EXCP_DEBUG);
+    } else {
+        switch (dc->is_jmp) {
+        case DISAS_NEXT:
+            gen_goto_tb(dc, 0, dc->pc);
+            break;
+        default:
+        case DISAS_JUMP:
+            break;
+        case DISAS_UPDATE:
+            /* indicate that the hash table must be used
+               to find the next TB */
+            tcg_gen_exit_tb(0);
+            break;
+        case DISAS_TB_JUMP:
+            /* nothing more to generate */
+            break;
+        }
+    }
+
+    gen_icount_end(tb, num_insns);
+    *gen_opc_ptr = INDEX_op_end;
+    if (search_pc) {
+        j = gen_opc_ptr - gen_opc_buf;
+        k++;
+        while (k <= j) {
+            gen_opc_instr_start[k++] = 0;
+        }
+    } else {
+        tb->size = dc->pc - pc_start;
+        tb->icount = num_insns;
+    }
+
+#ifdef DEBUG_DISAS
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+        qemu_log("\n");
+        log_target_disas(pc_start, dc->pc - pc_start, 0);
+        qemu_log("\nisize=%d osize=%td\n",
+            dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
+    }
+#endif
 }
 
 void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 09/16] target-or32: Add PIC support
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
                   ` (7 preceding siblings ...)
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 08/16] target-or32: Add instruction tanslation Jia Liu
@ 2012-06-21  2:58 ` Jia Liu
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 10/16] target-or32: Add timer support Jia Liu
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:58 UTC (permalink / raw)
  To: qemu-devel

Add OpenRISC Programmable Interrupt Controller support.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 hw/openrisc_pic.c |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/hw/openrisc_pic.c b/hw/openrisc_pic.c
index 0d14bbe..76bd792 100644
--- a/hw/openrisc_pic.c
+++ b/hw/openrisc_pic.c
@@ -28,3 +28,51 @@ void cpu_openrisc_pic_reset(CPUOpenRISCState *env)
     env->picmr = 0x00000000;
     env->picsr = 0x00000000;
 }
+
+/* OpenRISC pic handler */
+static void openrisc_pic_cpu_handler(void *opaque, int irq, int level)
+{
+    CPUOpenRISCState *env = (CPUOpenRISCState *)opaque;
+    int i;
+    uint32_t irq_bit = 1 << irq;
+
+    if (irq > 31 || irq < 0) {
+        return;
+    }
+
+    if (level) {
+        env->picsr |= irq_bit;
+    } else {
+        env->picsr &= ~irq_bit;
+    }
+
+    for (i = 0; i < 32; i++) {
+        if ((env->picsr && (1 << i)) && (env->picmr && (1 << i))) {
+            cpu_interrupt(env, CPU_INTERRUPT_HARD);
+        } else {
+            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+            env->picsr &= ~(1 << i);
+        }
+    }
+}
+
+void cpu_openrisc_pic_init(CPUOpenRISCState *env)
+{
+    int i;
+    qemu_irq *qi;
+    qi = qemu_allocate_irqs(openrisc_pic_cpu_handler, env, NR_IRQS);
+
+    for (i = 0; i < NR_IRQS; i++) {
+        env->irq[i] = qi[i];
+    }
+}
+
+void cpu_openrisc_store_picmr(CPUOpenRISCState *env, uint32_t value)
+{
+    env->picmr |= value;
+}
+
+void cpu_openrisc_store_picsr(CPUOpenRISCState *env, uint32_t value)
+{
+    env->picsr &= ~value;
+}
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 10/16] target-or32: Add timer support
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
                   ` (8 preceding siblings ...)
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 09/16] target-or32: Add PIC support Jia Liu
@ 2012-06-21  2:58 ` Jia Liu
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 11/16] target-or32: Add a IIS dummy board Jia Liu
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:58 UTC (permalink / raw)
  To: qemu-devel

Add OpenRISC timer support.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 hw/openrisc_timer.c |  130 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 130 insertions(+)

diff --git a/hw/openrisc_timer.c b/hw/openrisc_timer.c
index df384f6..25cde1a 100644
--- a/hw/openrisc_timer.c
+++ b/hw/openrisc_timer.c
@@ -22,9 +22,139 @@
 #include "openrisc_cpudev.h"
 #include "qemu-timer.h"
 
+#define TIMER_FREQ    (20 * 1000 * 1000)    /* 20MHz */
+
+/* The time when TTCR changes */
+static uint64_t last_clk;
+static int is_counting;
+
+/* Timer Mode */
+enum {
+    TIMER_NONE = (0 << 30),
+    TIMER_INTR = (1 << 30),
+    TIMER_SHOT = (2 << 30),
+    TIMER_CONT = (3 << 30),
+};
+
 /* Reset Timer */
 void cpu_openrisc_timer_reset(CPUOpenRISCState *env)
 {
     env->ttmr = 0x00000000;
     env->ttcr = 0x00000000;
 }
+
+static void count_update(CPUOpenRISCState *env)
+{
+    uint64_t now, next;
+    uint32_t wait;
+
+    now = qemu_get_clock_ns(vm_clock);
+    if (!is_counting) {
+        qemu_del_timer(env->timer);
+        last_clk = now;
+        return;
+    }
+
+    env->ttcr += (uint32_t)muldiv64(now - last_clk, TIMER_FREQ,
+                                    get_ticks_per_sec());
+    last_clk = now;
+
+    if ((env->ttmr & TTMR_TP) <= (env->ttcr & TTMR_TP)) {
+        wait = TTMR_TP - (env->ttcr & TTMR_TP) + 1;
+        wait += env->ttmr & TTMR_TP;
+    } else {
+        wait = (env->ttmr & TTMR_TP) - (env->ttcr & TTMR_TP);
+    }
+
+    next = now + muldiv64(wait, get_ticks_per_sec(), TIMER_FREQ);
+    qemu_mod_timer(env->timer, next);
+}
+
+static void count_start(CPUOpenRISCState *env)
+{
+    is_counting = 1;
+    count_update(env);
+}
+
+static void count_stop(CPUOpenRISCState *env)
+{
+    is_counting = 0;
+    count_update(env);
+}
+
+uint32_t cpu_openrisc_get_count(CPUOpenRISCState *env)
+{
+    count_update(env);
+    return env->ttcr;
+}
+
+void cpu_openrisc_store_count(CPUOpenRISCState *env, uint32_t count)
+{
+    /* Store new count register */
+    env->ttcr = count;
+    if (env->ttmr & TIMER_NONE) {
+        return;
+    }
+    count_start(env);
+}
+
+void cpu_openrisc_store_compare(CPUOpenRISCState *env, uint32_t value)
+{
+    int ip = env->ttmr & TTMR_IP;
+
+    if (value & TTMR_IP) { /* Keep IP bit */
+        env->ttmr = (value & ~TTMR_IP) + ip;
+    } else {               /* Clear IP bit */
+        env->ttmr = value & ~TTMR_IP;
+        env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
+    }
+    count_update(env);
+
+    switch (env->ttmr & TTMR_M) {
+    case TIMER_NONE:
+        count_stop(env);
+        break;
+    case TIMER_INTR:
+        count_start(env);
+        break;
+    case TIMER_SHOT:
+        count_start(env);
+        break;
+    case TIMER_CONT:
+        count_start(env);
+        break;
+    }
+}
+
+static void openrisc_timer_cb(void *opaque)
+{
+    CPUOpenRISCState *env = opaque;
+
+    if ((env->ttmr & TTMR_IE) &&
+         qemu_timer_expired(env->timer, qemu_get_clock_ns(vm_clock))) {
+        env->ttmr |= TTMR_IP;
+        env->interrupt_request |= CPU_INTERRUPT_TIMER;
+    }
+
+    switch (env->ttmr & TTMR_M) {
+    case TIMER_NONE:
+        break;
+    case TIMER_INTR:
+        env->ttcr = 0;
+        count_start(env);
+        break;
+    case TIMER_SHOT:
+        count_stop(env);
+        break;
+    case TIMER_CONT:
+        count_start(env);
+        break;
+    }
+}
+
+void cpu_openrisc_clock_init(CPUOpenRISCState *env)
+{
+    env->timer = qemu_new_timer_ns(vm_clock, &openrisc_timer_cb, env);
+    env->ttmr = 0;
+    env->ttcr = 0;
+}
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 11/16] target-or32: Add a IIS dummy board
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
                   ` (9 preceding siblings ...)
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 10/16] target-or32: Add timer support Jia Liu
@ 2012-06-21  2:58 ` Jia Liu
  2012-06-21  8:19   ` 陳韋任 (Wei-Ren Chen)
  2012-06-21  9:03   ` Peter Crosthwaite
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 12/16] target-or32: Add system instructions Jia Liu
                   ` (4 subsequent siblings)
  15 siblings, 2 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:58 UTC (permalink / raw)
  To: qemu-devel

Add a IIS dummy board.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 hw/openrisc/Makefile.objs |    2 +-
 hw/openrisc_sim.c         |  160 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+), 1 deletion(-)
 create mode 100644 hw/openrisc_sim.c

diff --git a/hw/openrisc/Makefile.objs b/hw/openrisc/Makefile.objs
index 1c541a5..38ff8f5 100644
--- a/hw/openrisc/Makefile.objs
+++ b/hw/openrisc/Makefile.objs
@@ -1,3 +1,3 @@
-obj-y = openrisc_pic.o openrisc_timer.o
+obj-y = openrisc_pic.o openrisc_sim.o openrisc_timer.o
 
 obj-y := $(addprefix ../,$(obj-y))
diff --git a/hw/openrisc_sim.c b/hw/openrisc_sim.c
new file mode 100644
index 0000000..892c67f
--- /dev/null
+++ b/hw/openrisc_sim.c
@@ -0,0 +1,160 @@
+/*
+ *  OpenRISC simulator for use as an ISS.
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
+ *                          Feng Gao <gf91597@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 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/>.
+ */
+
+#include "hw.h"
+#include "openrisc_cpudev.h"
+#include "boards.h"
+#include "elf.h"
+#include "pc.h"
+#include "loader.h"
+#include "exec-memory.h"
+#include "sysemu.h"
+#include "sysbus.h"
+#include "qtest.h"
+
+#define KERNEL_LOAD_ADDR 0x100
+
+static struct _loaderparams {
+    uint64_t ram_size;
+    const char *kernel_filename;
+    const char *kernel_cmdline;
+    const char *initrd_filename;
+} loaderparams;
+
+static void main_cpu_reset(void *opaque)
+{
+    CPUOpenRISCState *env = opaque;
+    cpu_reset(ENV_GET_CPU(env));
+}
+
+static void openrisc_sim_net_init(MemoryRegion *address_space,
+                                  target_phys_addr_t base,
+                                  target_phys_addr_t descriptors,
+                                  qemu_irq irq, NICInfo *nd)
+{
+    DeviceState *dev;
+    SysBusDevice *s;
+
+    dev = qdev_create(NULL, "open_eth");
+    qdev_set_nic_properties(dev, nd);
+    qdev_init_nofail(dev);
+
+    s = sysbus_from_qdev(dev);
+    sysbus_connect_irq(s, 0, irq);
+    memory_region_add_subregion(address_space, base,
+                                sysbus_mmio_get_region(s, 0));
+    memory_region_add_subregion(address_space, descriptors,
+                                sysbus_mmio_get_region(s, 1));
+}
+
+static uint64_t openrisc_load_kernel(void)
+{
+    long kernel_size;
+    uint64_t elf_entry;
+    target_phys_addr_t entry;
+
+    if (loaderparams.kernel_filename && !qtest_enabled()) {
+        kernel_size = load_elf(loaderparams.kernel_filename, NULL, NULL,
+                               &elf_entry, NULL, NULL, 1, ELF_MACHINE, 1);
+        entry = elf_entry;
+        if (kernel_size < 0) {
+            kernel_size = load_uimage(loaderparams.kernel_filename,
+                                      &entry, NULL, NULL);
+        }
+        if (kernel_size < 0) {
+            kernel_size = load_image_targphys(loaderparams.kernel_filename,
+                                              KERNEL_LOAD_ADDR,
+                                              ram_size - KERNEL_LOAD_ADDR);
+            entry = KERNEL_LOAD_ADDR;
+        }
+        if (kernel_size < 0) {
+            fprintf(stderr, "qemu: could not load kernel '%s'\n",
+                    loaderparams.kernel_filename);
+            exit(1);
+        }
+
+        if (kernel_size > 0) {
+            return elf_entry;
+        }
+    } else {
+        entry = 0;
+    }
+
+    return entry;
+}
+
+static void openrisc_sim_init(ram_addr_t ram_size,
+                              const char *boot_device,
+                              const char *kernel_filename,
+                              const char *kernel_cmdline,
+                              const char *initrd_filename,
+                              const char *cpu_model)
+{
+    CPUOpenRISCState *env;
+    MemoryRegion *ram = g_new(MemoryRegion, 1);
+
+    if (!cpu_model) {
+        cpu_model = "or1200";
+    }
+    env = cpu_init(cpu_model);
+    if (!env) {
+        fprintf(stderr, "Unable to find CPU definition!\n");
+        exit(1);
+    }
+
+    qemu_register_reset(main_cpu_reset, env);
+    main_cpu_reset(env);
+
+    memory_region_init_ram(ram, "openrisc.ram", ram_size);
+    memory_region_add_subregion(get_system_memory(), 0, ram);
+
+    if (kernel_filename) {
+        loaderparams.ram_size = ram_size;
+        loaderparams.kernel_filename = kernel_filename;
+        loaderparams.kernel_cmdline = kernel_cmdline;
+        env->pc = openrisc_load_kernel();
+    }
+
+    cpu_openrisc_pic_init(env);
+    cpu_openrisc_clock_init(env);
+
+    serial_mm_init(get_system_memory(), 0x90000000, 0,
+                   env->irq[2], 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);
+
+    if (nd_table[0].vlan) {
+        openrisc_sim_net_init(get_system_memory(), 0x92000000,
+                              0x92000400, env->irq[4], nd_table);
+    }
+}
+
+static QEMUMachine openrisc_sim_machine = {
+    .name = "or32-sim",
+    .desc = "or32 simulation",
+    .init = openrisc_sim_init,
+    .max_cpus = 1,
+    .is_default = 1,
+};
+
+static void openrisc_sim_machine_init(void)
+{
+    qemu_register_machine(&openrisc_sim_machine);
+}
+
+machine_init(openrisc_sim_machine_init);
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 12/16] target-or32: Add system instructions
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
                   ` (10 preceding siblings ...)
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 11/16] target-or32: Add a IIS dummy board Jia Liu
@ 2012-06-21  2:58 ` Jia Liu
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 13/16] target-or32: Add gdb stub Jia Liu
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:58 UTC (permalink / raw)
  To: qemu-devel

Add OpenRISC system instructions.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 target-openrisc/Makefile.objs |    3 +-
 target-openrisc/helper.h      |    4 +
 target-openrisc/sys_helper.c  |  244 +++++++++++++++++++++++++++++++++++++++++
 target-openrisc/translate.c   |   10 ++
 4 files changed, 260 insertions(+), 1 deletion(-)
 create mode 100644 target-openrisc/sys_helper.c

diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs
index 0d72c33..9d13a5d 100644
--- a/target-openrisc/Makefile.objs
+++ b/target-openrisc/Makefile.objs
@@ -1,3 +1,4 @@
 obj-$(CONFIG_SOFTMMU) += machine.o
 obj-y += cpu.o excp.o intrpt.o mmu.o translate.o
-obj-y += excp_helper.o fpu_helper.o int_helper.o intrpt_helper.o mmu_helper.o
+obj-y += excp_helper.o fpu_helper.o int_helper.o intrpt_helper.o \
+         mmu_helper.o sys_helper.o
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index 6eb259a..836a70b 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -63,4 +63,8 @@ DEF_HELPER_FLAGS_3(mul32, 0, tl, env, tl, tl)
 /* interrupt */
 DEF_HELPER_FLAGS_1(rfe, 0, void, env)
 
+/* sys */
+DEF_HELPER_FLAGS_4(mtspr, 0, void, env, tl, tl, tl)
+DEF_HELPER_FLAGS_4(mfspr, 0, tl, env, tl, tl, tl)
+
 #include "def-helper.h"
diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c
new file mode 100644
index 0000000..a2691dc
--- /dev/null
+++ b/target-openrisc/sys_helper.c
@@ -0,0 +1,244 @@
+/*
+ *  OpenRISC system instructions helper routines
+ *
+ *  Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
+ *                          Zhizhou Zhang <etouzh@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 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/>.
+ */
+
+#include "cpu.h"
+#include "helper.h"
+
+#define TO_SPR(group, number) (((group) << 11) + (number))
+
+void HELPER(mtspr)(CPUOpenRISCState *env,
+                   target_ulong ra, target_ulong rb, target_ulong offset)
+{
+#ifndef CONFIG_USER_ONLY
+    int spr = (ra | offset);
+    int idx;
+
+    switch (spr) {
+    case TO_SPR(0, 0): /* VR */
+        env->vr = rb;
+        break;
+
+    case TO_SPR(0, 16): /* NPC */
+        env->npc = rb;
+        break;
+
+    case TO_SPR(0, 17): /* SR */
+        if ((env->sr & (SR_IME | SR_DME | SR_SM)) ^
+            (rb & (SR_IME | SR_DME | SR_SM))) {
+            tlb_flush(env, 1);
+        }
+        env->sr = rb;
+        env->sr |= SR_FO;      /* FO is const equal to 1 */
+        if (env->sr & SR_DME) {
+            env->tlb->map_address_data = &get_phys_data;
+        } else {
+            env->tlb->map_address_data = &get_phys_nommu;
+        }
+
+        if (env->sr & SR_IME) {
+            env->tlb->map_address_code = &get_phys_code;
+        } else {
+            env->tlb->map_address_code = &get_phys_nommu;
+        }
+        break;
+
+    case TO_SPR(0, 18): /* PPC */
+        env->ppc = rb;
+        break;
+
+    case TO_SPR(0, 32): /* EPCR */
+        env->epcr = rb;
+        break;
+
+    case TO_SPR(0, 48): /* EEAR */
+        env->eear = rb;
+        break;
+
+    case TO_SPR(0, 64): /* ESR */
+        env->esr = rb;
+        break;
+    case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */
+        idx = spr - TO_SPR(1, 512);
+        if (!(rb & 1)) {
+            tlb_flush_page(env, env->tlb->dtlb[0][idx].mr & TARGET_PAGE_MASK);
+        }
+        env->tlb->dtlb[0][idx].mr = rb;
+        break;
+
+    case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */
+        idx = spr - TO_SPR(1, 640);
+        env->tlb->dtlb[0][idx].tr = rb;
+        break;
+    case TO_SPR(1, 768) ... TO_SPR(1, 895):   /* DTLBW1MR 0-127 */
+    case TO_SPR(1, 896) ... TO_SPR(1, 1023):  /* DTLBW1TR 0-127 */
+    case TO_SPR(1, 1024) ... TO_SPR(1, 1151): /* DTLBW2MR 0-127 */
+    case TO_SPR(1, 1152) ... TO_SPR(1, 1279): /* DTLBW2TR 0-127 */
+    case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */
+    case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */
+        break;
+    case TO_SPR(2, 512) ... TO_SPR(2, 639):   /* ITLBW0MR 0-127 */
+        idx = spr - TO_SPR(2, 512);
+        if (!(rb & 1)) {
+            tlb_flush_page(env, env->tlb->itlb[0][idx].mr & TARGET_PAGE_MASK);
+        }
+        env->tlb->itlb[0][idx].mr = rb;
+        break;
+
+    case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */
+        idx = spr - TO_SPR(2, 640);
+        env->tlb->itlb[0][idx].tr = rb;
+        break;
+    case TO_SPR(2, 768) ... TO_SPR(2, 895):   /* ITLBW1MR 0-127 */
+    case TO_SPR(2, 896) ... TO_SPR(2, 1023):  /* ITLBW1TR 0-127 */
+    case TO_SPR(2, 1024) ... TO_SPR(2, 1151): /* ITLBW2MR 0-127 */
+    case TO_SPR(2, 1152) ... TO_SPR(2, 1279): /* ITLBW2TR 0-127 */
+    case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */
+    case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
+        break;
+    case TO_SPR(9, 0):  /* PICMR */
+        cpu_openrisc_store_picmr(env, rb);
+        break;
+    case TO_SPR(9, 2):  /* PICSR */
+        cpu_openrisc_store_picsr(env, rb);
+        break;
+    case TO_SPR(10, 0): /* TTMR */
+        cpu_openrisc_store_compare(env, rb);
+        break;
+    case TO_SPR(10, 1): /* TTCR */
+        cpu_openrisc_store_count(env, rb);
+        break;
+    default:
+        break;
+    }
+#endif
+}
+
+target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
+                           target_ulong rd, target_ulong ra, uint32_t offset)
+{
+#ifndef CONFIG_USER_ONLY
+    int spr = (ra | offset);
+    int idx;
+
+    switch (spr) {
+    case TO_SPR(0, 0): /* VR */
+        return env->vr & SPR_VR;
+
+    case TO_SPR(0, 1): /* UPR */
+        return env->upr;    /* TT, DM, IM, UP present */
+
+    case TO_SPR(0, 2): /* CPUCFGR */
+        return env->cpucfgr;
+
+    case TO_SPR(0, 3): /* DMMUCFGR */
+        return env->dmmucfgr;    /* 1Way, 64 entries */
+
+    case TO_SPR(0, 4): /* IMMUCFGR */
+        return env->immucfgr;
+
+    case TO_SPR(0, 16): /* NPC */
+        return env->npc;
+
+    case TO_SPR(0, 17): /* SR */
+        return env->sr;
+
+    case TO_SPR(0, 18): /* PPC */
+        return env->ppc;
+
+    case TO_SPR(0, 32): /* EPCR */
+        return env->epcr;
+
+    case TO_SPR(0, 48): /* EEAR */
+        return env->eear;
+
+    case TO_SPR(0, 64): /* ESR */
+        return env->esr;
+
+    case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */
+        idx = spr - TO_SPR(1, 512);
+        return env->tlb->dtlb[0][idx].mr;
+
+    case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */
+        idx = spr - TO_SPR(1, 640);
+        return env->tlb->dtlb[0][idx].tr;
+
+    case TO_SPR(1, 768) ... TO_SPR(1, 895):   /* DTLBW1MR 0-127 */
+    case TO_SPR(1, 896) ... TO_SPR(1, 1023):  /* DTLBW1TR 0-127 */
+    case TO_SPR(1, 1024) ... TO_SPR(1, 1151): /* DTLBW2MR 0-127 */
+    case TO_SPR(1, 1152) ... TO_SPR(1, 1279): /* DTLBW2TR 0-127 */
+    case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */
+    case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */
+        break;
+
+    case TO_SPR(2, 512) ... TO_SPR(2, 639): /* ITLBW0MR 0-127 */
+        idx = spr - TO_SPR(2, 512);
+        return env->tlb->itlb[0][idx].mr;
+
+    case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */
+        idx = spr - TO_SPR(2, 640);
+        return env->tlb->itlb[0][idx].tr;
+
+    case TO_SPR(2, 768) ... TO_SPR(2, 895):   /* ITLBW1MR 0-127 */
+    case TO_SPR(2, 896) ... TO_SPR(2, 1023):  /* ITLBW1TR 0-127 */
+    case TO_SPR(2, 1024) ... TO_SPR(2, 1151): /* ITLBW2MR 0-127 */
+    case TO_SPR(2, 1152) ... TO_SPR(2, 1279): /* ITLBW2TR 0-127 */
+    case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */
+    case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
+        break;
+
+    case TO_SPR(9, 0):  /* PICMR */
+        return env->picmr;
+
+    case TO_SPR(9, 2):  /* PICSR */
+        return env->picsr;
+
+    case TO_SPR(10, 0): /* TTMR */
+        return env->ttmr;
+
+    case TO_SPR(10, 1): /* TTCR */
+        return cpu_openrisc_get_count(env);
+
+    default:
+        break;
+    }
+#endif
+
+/*If we later need to add tracepoints (or debug printfs) for the return
+value, it may be useful to structure the code like this:
+
+target_ulong ret = 0;
+
+switch() {
+case x:
+ ret = y;
+ break;
+case z:
+ ret = 42;
+ break;
+...
+}
+
+later something like trace_spr_read(ret);
+
+return ret;*/
+
+    /* for rd is passed in, if rd unchanged, just keep it back.  */
+    return rd;
+}
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 300236f..0aa7b91 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -976,10 +976,20 @@ static void dec_misc(DisasContext *dc, CPUOpenRISCState *env, uint32_t insn)
 
     case 0x2d:   /*l.mfspr*/
         LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, I16);
+        {
+            TCGv_i32 ti = tcg_const_i32(I16);
+            gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti);
+            tcg_temp_free_i32(ti);
+        }
         break;
 
     case 0x30:  /*l.mtspr*/
         LOG_DIS("l.mtspr %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        {
+            TCGv_i32 im = tcg_const_i32(tmp);
+            gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im);
+            tcg_temp_free_i32(im);
+        }
         break;
 
     case 0x34:   /*l.sd*/
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 13/16] target-or32: Add gdb stub
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
                   ` (11 preceding siblings ...)
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 12/16] target-or32: Add system instructions Jia Liu
@ 2012-06-21  2:58 ` Jia Liu
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 14/16] target-or32: Add linux syscall, signal and termbits Jia Liu
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:58 UTC (permalink / raw)
  To: qemu-devel

Add OpenRISC gdb stub support.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 gdbstub.c |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/gdbstub.c b/gdbstub.c
index 08cf864..5d37dd9 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1155,6 +1155,68 @@ static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
 
     return sizeof(target_ulong);
 }
+#elif defined(TARGET_OPENRISC)
+
+#define NUM_CORE_REGS (32 + 3)
+
+static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n)
+{
+    if (n < 32) {
+        GET_REG32(env->gpr[n]);
+    } else {
+        switch (n) {
+        case 32:    /* PPC */
+            GET_REG32(env->ppc);
+            break;
+
+        case 33:    /* NPC */
+            GET_REG32(env->npc);
+            break;
+
+        case 34:    /* SR */
+            GET_REG32(env->sr);
+            break;
+
+        default:
+            break;
+        }
+    }
+    return 0;
+}
+
+static int cpu_gdb_write_register(CPUOpenRISCState *env,
+                                  uint8_t *mem_buf, int n)
+{
+    uint32_t tmp;
+
+    if (n > NUM_CORE_REGS) {
+        return 0;
+    }
+
+    tmp = ldl_p(mem_buf);
+
+    if (n < 32) {
+        env->gpr[n] = tmp;
+    } else {
+        switch (n) {
+        case 32: /* PPC */
+            env->ppc = tmp;
+            break;
+
+        case 33: /* NPC */
+            env->npc = tmp;
+            break;
+
+        case 34: /* SR */
+            env->sr = tmp;
+            break;
+
+        default:
+            break;
+        }
+    }
+    return 4;
+}
 #elif defined (TARGET_SH4)
 
 /* Hint: Use "set architecture sh4" in GDB to see fpu registers */
@@ -1924,6 +1986,8 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
     }
 #elif defined (TARGET_MICROBLAZE)
     s->c_cpu->sregs[SR_PC] = pc;
+#elif defined(TARGET_OPENRISC)
+    s->c_cpu->pc = pc;
 #elif defined (TARGET_CRIS)
     s->c_cpu->pc = pc;
 #elif defined (TARGET_ALPHA)
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 14/16] target-or32: Add linux syscall, signal and termbits
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
                   ` (12 preceding siblings ...)
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 13/16] target-or32: Add gdb stub Jia Liu
@ 2012-06-21  2:58 ` Jia Liu
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 15/16] target-or32: Add linux user support Jia Liu
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 16/16] target-or32: Add testcases Jia Liu
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:58 UTC (permalink / raw)
  To: qemu-devel

Add OpenRISC linux syscall, signal and termbits.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 linux-user/openrisc/syscall.h       |   24 ++
 linux-user/openrisc/syscall_nr.h    |  506 +++++++++++++++++++++++++++++++++++
 linux-user/openrisc/target_signal.h |   26 ++
 linux-user/openrisc/termbits.h      |  294 ++++++++++++++++++++
 4 files changed, 850 insertions(+)
 create mode 100644 linux-user/openrisc/syscall.h
 create mode 100644 linux-user/openrisc/syscall_nr.h
 create mode 100644 linux-user/openrisc/target_signal.h
 create mode 100644 linux-user/openrisc/termbits.h

diff --git a/linux-user/openrisc/syscall.h b/linux-user/openrisc/syscall.h
new file mode 100644
index 0000000..bdbb577
--- /dev/null
+++ b/linux-user/openrisc/syscall.h
@@ -0,0 +1,24 @@
+struct target_pt_regs {
+    union {
+        struct {
+            /* Named registers */
+            uint32_t sr;       /* Stored in place of r0 */
+            target_ulong sp;   /* r1 */
+        };
+        struct {
+            /* Old style */
+            target_ulong offset[2];
+            target_ulong gprs[30];
+        };
+        struct {
+            /* New style */
+            target_ulong gpr[32];
+        };
+    };
+    target_ulong pc;
+    target_ulong orig_gpr11;   /* For restarting system calls */
+    uint32_t syscallno;        /* Syscall number (used by strace) */
+    target_ulong dummy;     /* Cheap alignment fix */
+};
+
+#define UNAME_MACHINE "openrisc"
diff --git a/linux-user/openrisc/syscall_nr.h b/linux-user/openrisc/syscall_nr.h
new file mode 100644
index 0000000..f4ac91e
--- /dev/null
+++ b/linux-user/openrisc/syscall_nr.h
@@ -0,0 +1,506 @@
+#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
+
+/* fs/xattr.c */
+#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
+
+/* fs/dcache.c */
+#define TARGET_NR_getcwd 17
+
+/* fs/cookies.c */
+#define TARGET_NR_lookup_dcookie 18
+
+/* fs/eventfd.c */
+#define TARGET_NR_eventfd2 19
+
+/* fs/eventpoll.c */
+#define TARGET_NR_epoll_create1 20
+#define TARGET_NR_epoll_ctl 21
+#define TARGET_NR_epoll_pwait 22
+
+/* fs/fcntl.c */
+#define TARGET_NR_dup 23
+#define TARGET_NR_dup3 24
+#define TARGET_NR_3264_fcntl 25
+
+/* fs/inotify_user.c */
+#define TARGET_NR_inotify_init1 26
+#define TARGET_NR_inotify_add_watch 27
+#define TARGET_NR_inotify_rm_watch 28
+
+/* fs/ioctl.c */
+#define TARGET_NR_ioctl 29
+
+/* fs/ioprio.c */
+#define TARGET_NR_ioprio_set 30
+#define TARGET_NR_ioprio_get 31
+
+/* fs/locks.c */
+#define TARGET_NR_flock 32
+
+/* fs/namei.c */
+#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
+
+/* fs/namespace.c */
+#define TARGET_NR_umount2 39
+#define TARGET_NR_mount 40
+#define TARGET_NR_pivot_root 41
+
+/* fs/nfsctl.c */
+#define TARGET_NR_nfsservctl 42
+
+/* fs/open.c */
+#define TARGET_NR_3264_statfs 43
+#define TARGET_NR_3264_fstatfs 44
+#define TARGET_NR_3264_truncate 45
+#define TARGET_NR_3264_ftruncate 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
+
+/* fs/pipe.c */
+#define TARGET_NR_pipe2 59
+
+/* fs/quota.c */
+#define TARGET_NR_quotactl 60
+
+/* fs/readdir.c */
+#define TARGET_NR_getdents64 61
+
+/* fs/read_write.c */
+#define TARGET_NR_3264_lseek 62
+#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
+
+/* fs/sendfile.c */
+#define TARGET_NR_3264_sendfile 71
+
+/* fs/select.c */
+#define TARGET_NR_pselect6 72
+#define TARGET_NR_ppoll 73
+
+/* fs/signalfd.c */
+#define TARGET_NR_signalfd4 74
+
+/* fs/splice.c */
+#define TARGET_NR_vmsplice 75
+#define TARGET_NR_splice 76
+#define TARGET_NR_tee 77
+
+/* fs/stat.c */
+#define TARGET_NR_readlinkat 78
+#define TARGET_NR_3264_fstatat 79
+#define TARGET_NR_3264_fstat 80
+
+/* fs/sync.c */
+#define TARGET_NR_sync 81
+#define TARGET_NR_fsync 82
+#define TARGET_NR_fdatasync 83
+
+#ifdef __ARCH_WANT_SYNC_FILE_RANGE2
+#define TARGET_NR_sync_file_range2 84
+#else
+#define TARGET_NR_sync_file_range 84
+#endif
+
+/* fs/timerfd.c */
+#define TARGET_NR_timerfd_create 85
+#define TARGET_NR_timerfd_settime 86
+#define TARGET_NR_timerfd_gettime 87
+
+/* fs/utimes.c */
+#define TARGET_NR_utimensat 88
+
+/* kernel/acct.c */
+#define TARGET_NR_acct 89
+
+/* kernel/capability.c */
+#define TARGET_NR_capget 90
+#define TARGET_NR_capset 91
+
+/* kernel/exec_domain.c */
+#define TARGET_NR_personality 92
+
+/* kernel/exit.c */
+#define TARGET_NR_exit 93
+#define TARGET_NR_exit_group 94
+#define TARGET_NR_waitid 95
+
+/* kernel/fork.c */
+#define TARGET_NR_set_tid_address 96
+#define TARGET_NR_unshare 97
+
+/* kernel/futex.c */
+#define TARGET_NR_futex 98
+#define TARGET_NR_set_robust_list 99
+#define TARGET_NR_get_robust_list 100
+
+/* kernel/hrtimer.c */
+#define TARGET_NR_nanosleep 101
+
+/* kernel/itimer.c */
+#define TARGET_NR_getitimer 102
+#define TARGET_NR_setitimer 103
+
+/* kernel/kexec.c */
+#define TARGET_NR_kexec_load 104
+
+/* kernel/module.c */
+#define TARGET_NR_init_module 105
+#define TARGET_NR_delete_module 106
+
+/* kernel/posix-timers.c */
+#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
+
+/* kernel/printk.c */
+#define TARGET_NR_syslog 116
+
+/* kernel/ptrace.c */
+#define TARGET_NR_ptrace 117
+
+/* kernel/sched.c */
+#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
+
+/* kernel/signal.c */
+#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
+
+/* kernel/sys.c */
+#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
+
+/* kernel/time.c */
+#define TARGET_NR_gettimeofday 169
+#define TARGET_NR_settimeofday 170
+#define TARGET_NR_adjtimex 171
+
+/* kernel/timer.c */
+#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
+
+/* ipc/mqueue.c */
+#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
+
+/* ipc/msg.c */
+#define TARGET_NR_msgget 186
+#define TARGET_NR_msgctl 187
+#define TARGET_NR_msgrcv 188
+#define TARGET_NR_msgsnd 189
+
+/* ipc/sem.c */
+#define TARGET_NR_semget 190
+#define TARGET_NR_semctl 191
+#define TARGET_NR_semtimedop 192
+#define TARGET_NR_semop 193
+
+/* ipc/shm.c */
+#define TARGET_NR_shmget 194
+#define TARGET_NR_shmctl 195
+#define TARGET_NR_shmat 196
+#define TARGET_NR_shmdt 197
+
+/* net/socket.c */
+#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
+
+/* mm/filemap.c */
+#define TARGET_NR_readahead 213
+
+/* mm/nommu.c, also with MMU */
+#define TARGET_NR_brk 214
+#define TARGET_NR_munmap 215
+#define TARGET_NR_mremap 216
+
+/* security/keys/keyctl.c */
+#define TARGET_NR_add_key 217
+#define TARGET_NR_request_key 218
+#define TARGET_NR_keyctl 219
+
+/* arch/example/kernel/sys_example.c */
+#define TARGET_NR_clone 220
+#define TARGET_NR_execve 221
+
+#define TARGET_NR_3264_mmap 222
+/* mm/fadvise.c */
+#define TARGET_NR_3264_fadvise64 223
+
+/* mm/, CONFIG_MMU only */
+#ifndef __ARCH_NOMMU
+#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
+#endif
+
+#define TARGET_NR_rt_tgsigqueueinfo 240
+#define TARGET_NR_perf_event_open 241
+#define TARGET_NR_accept4 242
+#define TARGET_NR_recvmmsg 243
+
+/*
+ * Architectures may provide up to 16 syscalls of their own
+ * starting with this value.
+ */
+#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
+
+#undef TARGET_NR_syscalls
+#define TARGET_NR_syscalls 270
+
+/*
+ * All syscalls below here should go away really,
+ * these are provided for both review and as a porting
+ * help for the C library version.
+*
+ * Last chance: are any of these important enough to
+ * enable by default?
+ */
+#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
+
+#undef TARGET_NR_syscalls
+#define TARGET_NR_syscalls (TARGET_NR_3264_lstat+1)
+
+#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
+
+#undef TARGET_NR_syscalls
+#define TARGET_NR_syscalls (TARGET_NR_signalfd+1)
+
+
+#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 __ARCH_WANT_SYS_FADVISE64
+#define TARGET_NR_newfstatat 1054
+#define __ARCH_WANT_SYS_NEWFSTATAT
+#define TARGET_NR_fstatfs 1055
+#define TARGET_NR_statfs 1056
+#define TARGET_NR_lseek 1057
+#define TARGET_NR_mmap 1058
+
+#undef TARGET_NR_syscalls
+#define TARGET_NR_syscalls (TARGET_NR_mmap+1)
+
+#define TARGET_NR_alarm 1059
+#define __ARCH_WANT_SYS_ALARM
+#define TARGET_NR_getpgrp 1060
+#define __ARCH_WANT_SYS_GETPGRP
+#define TARGET_NR_pause 1061
+#define __ARCH_WANT_SYS_PAUSE
+#define TARGET_NR_time 1062
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_COMPAT_SYS_TIME
+#define TARGET_NR_utime 1063
+#define __ARCH_WANT_SYS_UTIME
+
+#define TARGET_NR_creat 1064
+#define TARGET_NR_getdents 1065
+#define __ARCH_WANT_SYS_GETDENTS
+#define TARGET_NR_futimesat 1066
+#define TARGET_NR_select 1067
+#define __ARCH_WANT_SYS_SELECT
+#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 __ARCH_WANT_SYS_OLDUMOUNT
+#define TARGET_NR_uselib 1077
+#define TARGET_NR__sysctl 1078
+
+#define TARGET_NR_fork 1079
+
+#undef TARGET_NR_syscalls
+#define TARGET_NR_syscalls (TARGET_NR_fork+1)
+
+
+/*
+ * 32 bit systems traditionally used different
+ * syscalls for off_t and loff_t arguments, while
+ * 64 bit systems only need the off_t version.
+ * For new 32 bit platforms, there is no need to
+ * implement the old 32 bit off_t syscalls, so
+ * they take different names.
+ * Here we map the numbers so that both versions
+ * use the same syscall table layout.
+ */
+
+#define TARGET_NR_fcntl64 TARGET_NR_3264_fcntl
+#define TARGET_NR_statfs64 TARGET_NR_3264_statfs
+#define TARGET_NR_fstatfs64 TARGET_NR_3264_fstatfs
+#define TARGET_NR_truncate64 TARGET_NR_3264_truncate
+#define TARGET_NR_ftruncate64 TARGET_NR_3264_ftruncate
+#define TARGET_NR_llseek TARGET_NR_3264_lseek
+#define TARGET_NR_sendfile64 TARGET_NR_3264_sendfile
+#define TARGET_NR_fstatat64 TARGET_NR_3264_fstatat
+#define TARGET_NR_fstat64 TARGET_NR_3264_fstat
+#define TARGET_NR_mmap2 TARGET_NR_3264_mmap
+#define TARGET_NR_fadvise64_64 TARGET_NR_3264_fadvise64
+
+#ifdef TARGET_NR_3264_stat
+#define TARGET_NR_stat64 TARGET_NR_3264_stat
+#define TARGET_NR_lstat64 TARGET_NR_3264_lstat
+#endif
diff --git a/linux-user/openrisc/target_signal.h b/linux-user/openrisc/target_signal.h
new file mode 100644
index 0000000..964aed6
--- /dev/null
+++ b/linux-user/openrisc/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(CPUOpenRISCState *state)
+{
+    return state->gpr[1];
+}
+
+#endif /* TARGET_SIGNAL_H */
diff --git a/linux-user/openrisc/termbits.h b/linux-user/openrisc/termbits.h
new file mode 100644
index 0000000..373af77
--- /dev/null
+++ b/linux-user/openrisc/termbits.h
@@ -0,0 +1,294 @@
+typedef unsigned char   target_openrisc_cc;        /*cc_t*/
+typedef unsigned int    target_openrisc_speed;     /*speed_t*/
+typedef unsigned int    target_openrisc_tcflag;    /*tcflag_t*/
+
+#define TARGET_NCCS 19
+struct target_termios {
+    target_openrisc_tcflag c_iflag;               /* input mode flags */
+    target_openrisc_tcflag c_oflag;               /* output mode flags */
+    target_openrisc_tcflag c_cflag;               /* control mode flags */
+    target_openrisc_tcflag c_lflag;               /* local mode flags */
+    target_openrisc_cc c_line;                    /* line discipline */
+    target_openrisc_cc c_cc[TARGET_NCCS];         /* control characters */
+};
+
+struct target_termios2 {
+    target_openrisc_tcflag c_iflag;               /* input mode flags */
+    target_openrisc_tcflag c_oflag;               /* output mode flags */
+    target_openrisc_tcflag c_cflag;               /* control mode flags */
+    target_openrisc_tcflag c_lflag;               /* local mode flags */
+    target_openrisc_cc c_line;                    /* line discipline */
+    target_openrisc_cc c_cc[TARGET_NCCS];         /* control characters */
+    target_openrisc_speed c_ispeed;               /* input speed */
+    target_openrisc_speed c_ospeed;               /* output speed */
+};
+
+struct target_termios3 {
+    target_openrisc_tcflag c_iflag;               /* input mode flags */
+    target_openrisc_tcflag c_oflag;               /* output mode flags */
+    target_openrisc_tcflag c_cflag;               /* control mode flags */
+    target_openrisc_tcflag c_lflag;               /* local mode flags */
+    target_openrisc_cc c_line;                    /* line discipline */
+    target_openrisc_cc c_cc[TARGET_NCCS];         /* control characters */
+    target_openrisc_speed c_ispeed;               /* input speed */
+    target_openrisc_speed c_ospeed;               /* output speed */
+};
+
+/* c_cc characters */
+#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
+
+/* 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_BOTHER   0010000
+#define TARGET_B57600   0010001
+#define TARGET_B115200  0010002
+#define TARGET_B230400  0010003
+#define TARGET_B460800  0010004
+#define TARGET_B500000  0010005
+#define TARGET_B576000  0010006
+#define TARGET_B921600  0010007
+#define TARGET_B1000000 0010010
+#define TARGET_B1152000 0010011
+#define TARGET_B1500000 0010012
+#define TARGET_B2000000 0010013
+#define TARGET_B2500000 0010014
+#define TARGET_B3000000 0010015
+#define TARGET_B3500000 0010016
+#define TARGET_B4000000 0010017
+#define TARGET_CIBAUD   002003600000   /* input baud rate */
+#define TARGET_CMSPAR   010000000000   /* mark or space (stick) parity */
+#define TARGET_CRTSCTS  020000000000   /* flow control */
+
+#define TARGET_IBSHIFT   16            /* Shift from CBAUD to CIBAUD */
+
+/* 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
+#define TARGET_EXTPROC 0200000
+
+/* tcflow() and TCXONC use these */
+#define TARGET_TCOOFF          0
+#define TARGET_TCOON           1
+#define TARGET_TCIOFF          2
+#define TARGET_TCION           3
+
+/* tcflush() and TCFLSH use these */
+#define TARGET_TCIFLUSH        0
+#define TARGET_TCOFLUSH        1
+#define TARGET_TCIOFLUSH       2
+
+/* tcsetattr uses these */
+#define TARGET_TCSANOW         0
+#define TARGET_TCSADRAIN       1
+#define TARGET_TCSAFLUSH       2
+
+/* 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         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_TIOCSBRK        0x5427  /* BSD compatibility */
+#define TARGET_TIOCCBRK        0x5428  /* BSD compatibility */
+#define TARGET_TIOCGSID        0x5429  /* Return the session ID of FD */
+#define TARGET_TCGETS2         TARGET_IOR('T', 0x2A, struct termios2)
+#define TARGET_TCSETS2         TARGET_IOW('T', 0x2B, struct termios2)
+#define TARGET_TCSETSW2        TARGET_IOW('T', 0x2C, struct termios2)
+#define TARGET_TCSETSF2        TARGET_IOW('T', 0x2D, struct termios2)
+#define TARGET_TIOCGRS485      0x542E
+#ifndef TARGET_TIOCSRS485
+#define TARGET_TIOCSRS485      0x542F
+#endif
+/* Get Pty Number (of pty-mux device) */
+#define TARGET_TIOCGPTN        TARGET_IOR('T', 0x30, unsigned int)
+/* Lock/unlock Pty */
+#define TARGET_TIOCSPTLCK      TARGET_IOW('T', 0x31, int)
+/* Get primary device node of /dev/console */
+#define TARGET_TIOCGDEV        TARGET_IOR('T', 0x32, unsigned int)
+#define TARGET_TCGETX          0x5432 /* SYS5 TCGETX compatibility */
+#define TARGET_TCSETX          0x5433
+#define TARGET_TCSETXF         0x5434
+#define TARGET_TCSETXW         0x5435
+/* pty: generate signal */
+#define TARGET_TIOCSIG         TARGET_IOW('T', 0x36, int)
+#define TARGET_TIOCVHANGUP     0x5437
+
+#define TARGET_FIONCLEX        0x5450
+#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 */
+
+/* wait for a change on serial input line(s) */
+#define TARGET_TIOCMIWAIT      0x545C
+/* read serial port inline interrupt counts */
+#define TARGET_TIOCGICOUNT     0x545D
+
+/*
+ * Some arches already define TARGET_FIOQSIZE due to a historical
+ * conflict with a Hayes modem-specific ioctl value.
+ */
+#ifndef TARGET_FIOQSIZE
+#define TARGET_FIOQSIZE        0x5460
+#endif
+
+/* 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_TIOCPKT_IOCTL           64
+
+#define TARGET_TIOCSER_TEMT    0x01    /* Transmitter physically empty */
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 15/16] target-or32: Add linux user support
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
                   ` (13 preceding siblings ...)
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 14/16] target-or32: Add linux syscall, signal and termbits Jia Liu
@ 2012-06-21  2:58 ` Jia Liu
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 16/16] target-or32: Add testcases Jia Liu
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:58 UTC (permalink / raw)
  To: qemu-devel

Add QEMU OpenRISC linux user support.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 configure                           |    1 +
 default-configs/or32-linux-user.mak |    1 +
 linux-user/elfload.c                |   41 +++++++
 linux-user/main.c                   |  100 +++++++++++++++
 linux-user/signal.c                 |  229 +++++++++++++++++++++++++++++++++++
 linux-user/syscall.c                |    2 +-
 linux-user/syscall_defs.h           |   40 +++++-
 target-openrisc/cpu.h               |   12 ++
 8 files changed, 422 insertions(+), 4 deletions(-)
 create mode 100644 default-configs/or32-linux-user.mak

diff --git a/configure b/configure
index 80ee0be..c4d6339 100755
--- a/configure
+++ b/configure
@@ -951,6 +951,7 @@ microblaze-linux-user \
 microblazeel-linux-user \
 mips-linux-user \
 mipsel-linux-user \
+or32-linux-user \
 ppc-linux-user \
 ppc64-linux-user \
 ppc64abi32-linux-user \
diff --git a/default-configs/or32-linux-user.mak b/default-configs/or32-linux-user.mak
new file mode 100644
index 0000000..808c1f9
--- /dev/null
+++ b/default-configs/or32-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for or32-linux-user
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index f3b1552..6b622d4 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -787,6 +787,47 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMBState *env
 
 #endif /* TARGET_MICROBLAZE */
 
+#ifdef TARGET_OPENRISC
+
+#define ELF_START_MMAP 0x08000000
+
+#define elf_check_arch(x) ((x) == EM_OPENRISC)
+
+#define ELF_ARCH EM_OPENRISC
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA  ELFDATA2MSB
+
+static inline void init_thread(struct target_pt_regs *regs,
+                               struct image_info *infop)
+{
+    regs->pc = infop->entry;
+    regs->gpr[1] = infop->start_stack;
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE 8192
+
+/* See linux kernel arch/openrisc/include/asm/elf.h.  */
+#define ELF_NREG 34 /* gprs and pc, sr */
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+static void elf_core_copy_regs(target_elf_gregset_t *regs,
+                               const CPUOpenRISCState *env)
+{
+    int i;
+
+    for (i = 0; i < 32; i++) {
+        (*regs)[i] = tswapl(env->gpr[i]);
+    }
+
+    (*regs)[32] = tswapl(env->pc);
+    (*regs)[33] = tswapl(env->sr);
+}
+#define ELF_HWCAP 0
+#define ELF_PLATFORM NULL
+
+#endif /* TARGET_OPENRISC */
+
 #ifdef TARGET_SH4
 
 #define ELF_START_MMAP 0x80000000
diff --git a/linux-user/main.c b/linux-user/main.c
index 49108b8..a066479 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2305,6 +2305,93 @@ done_syscall:
 }
 #endif
 
+#ifdef TARGET_OPENRISC
+
+void cpu_loop(CPUOpenRISCState *env)
+{
+    int trapnr, gdbsig;
+
+    for (;;) {
+        trapnr = cpu_exec(env);
+        gdbsig = 0;
+
+        switch (trapnr) {
+        case EXCP_RESET:
+            fprintf(stderr, "\nReset request, exit, pc is %#x\n", env->pc);
+            exit(1);
+            break;
+        case EXCP_BUSERR:
+            fprintf(stderr, "\nBus error, exit, pc is %#x\n", env->pc);
+            gdbsig = SIGBUS;
+            break;
+        case EXCP_DPF:
+        case EXCP_IPF:
+            cpu_dump_state(env, stderr, fprintf, 0);
+            gdbsig = TARGET_SIGSEGV;
+            break;
+        case EXCP_TICK:
+            fprintf(stderr, "\nTick time interrupt pc is %#x\n", env->pc);
+            break;
+        case EXCP_ALIGN:
+            fprintf(stderr, "\nAlignment pc is %#x\n", env->pc);
+            gdbsig = SIGBUS;
+            break;
+        case EXCP_ILLEGAL:
+            fprintf(stderr, "\nIllegal instructionpc is %#x\n", env->pc);
+            gdbsig = SIGILL;
+            break;
+        case EXCP_INT:
+            fprintf(stderr, "\nExternal interruptpc is %#x\n", env->pc);
+            break;
+        case EXCP_DTLBMISS:
+        case EXCP_ITLBMISS:
+            printf("TLB miss\n");
+            break;
+        case EXCP_RANGE:
+            fprintf(stderr, "\nRange\n");
+            gdbsig = SIGSEGV;
+            break;
+        case EXCP_SYSCALL:
+            env->pc += 4;   /* 0xc00; */
+            env->gpr[11] = do_syscall(env,
+                                      env->gpr[11], /* return value       */
+                                      env->gpr[3],  /* r3 - r7 are params */
+                                      env->gpr[4],
+                                      env->gpr[5],
+                                      env->gpr[6],
+                                      env->gpr[7],
+                                      env->gpr[8], 0, 0);
+            break;
+        case EXCP_FPE:
+            fprintf(stderr, "Floating point error\n");
+            break;
+        case EXCP_TRAP:
+            fprintf(stderr, "Trap\n");
+            gdbsig = SIGTRAP;
+            break;
+        case EXCP_NR:
+            fprintf(stderr, "NR\n");
+            break;
+        default:
+            fprintf(stderr, "qemu: unhandled CPU exception %#x - aborting\n", \
+                    trapnr);
+            cpu_dump_state(env, stderr, fprintf, 0);
+            gdbsig = TARGET_SIGILL;
+            break;
+        }
+        if (gdbsig) {
+            gdb_handlesig(env, gdbsig);
+            if (gdbsig != TARGET_SIGTRAP) {
+                exit(1);
+            }
+        }
+
+        process_pending_signals(env);
+    }
+}
+
+#endif /* TARGET_OPENRISC */
+
 #ifdef TARGET_SH4
 void cpu_loop(CPUSH4State *env)
 {
@@ -3385,6 +3472,8 @@ int main(int argc, char **argv, char **envp)
 #else
         cpu_model = "24Kf";
 #endif
+#elif defined TARGET_OPENRISC
+        cpu_model = "or1200";
 #elif defined(TARGET_PPC)
 #ifdef TARGET_PPC64
         cpu_model = "970fx";
@@ -3787,6 +3876,17 @@ int main(int argc, char **argv, char **envp)
             env->hflags |= MIPS_HFLAG_M16;
         }
     }
+#elif defined(TARGET_OPENRISC)
+    {
+        int i;
+
+        for (i = 0; i < 32; i++) {
+            env->gpr[i] = regs->gpr[i];
+        }
+
+        env->sr = regs->sr;
+        env->pc = regs->pc;
+    }
 #elif defined(TARGET_SH4)
     {
         int i;
diff --git a/linux-user/signal.c b/linux-user/signal.c
index b1e139d..e06b6a8 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -3629,6 +3629,235 @@ long do_rt_sigreturn(CPUCRISState *env)
     return -TARGET_ENOSYS;
 }
 
+#elif defined(TARGET_OPENRISC)
+
+struct target_sigcontext {
+    struct target_pt_regs regs;
+    abi_ulong oldmask;
+    abi_ulong usp;
+};
+
+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 {
+    abi_ulong pinfo;
+    uint64_t puc;
+    struct target_siginfo info;
+    struct target_sigcontext sc;
+    struct target_ucontext uc;
+    unsigned char retcode[16];  /* trampoline code */
+};
+
+/* This is the asm-generic/ucontext.h version */
+#if 0
+static int restore_sigcontext(CPUOpenRISCState *regs,
+                              struct target_sigcontext *sc)
+{
+    unsigned int err = 0;
+    unsigned long old_usp;
+
+    /* Alwys make any pending restarted system call return -EINTR */
+    current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+    /* restore the regs from &sc->regs (same as sc, since regs is first)
+     * (sc is already checked for VERIFY_READ since the sigframe was
+     *  checked in sys_sigreturn previously)
+     */
+
+    if (copy_from_user(regs, &sc, sizeof(struct target_pt_regs))) {
+        goto badframe;
+    }
+
+    /* make sure the U-flag is set so user-mode cannot fool us */
+
+    regs->sr &= ~SR_SM;
+
+    /* restore the old USP as it was before we stacked the sc etc.
+     * (we cannot just pop the sigcontext since we aligned the sp and
+     *  stuff after pushing it)
+     */
+
+    err |= __get_user(old_usp, &sc->usp);
+    phx_signal("old_usp 0x%lx", old_usp);
+
+    __PHX__ REALLY           /* ??? */
+    wrusp(old_usp);
+    regs->gpr[1] = old_usp;
+
+    /* TODO: the other ports use regs->orig_XX to disable syscall checks
+     * after this completes, but we don't use that mechanism. maybe we can
+     * use it now ?
+     */
+
+    return err;
+
+badframe:
+    return 1;
+}
+#endif
+
+/* Set up a signal frame.  */
+
+static int setup_sigcontext(struct target_sigcontext *sc,
+                            CPUOpenRISCState *regs,
+                            unsigned long mask)
+{
+    int err = 0;
+    unsigned long usp = regs->gpr[1];
+
+    /* copy the regs. they are first in sc so we can use sc directly */
+
+    /*err |= copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
+
+    /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
+       the signal handler. The frametype will be restored to its previous
+       value in restore_sigcontext. */
+    /*regs->frametype = CRIS_FRAME_NORMAL;*/
+
+    /* then some other stuff */
+    err |= __put_user(mask, &sc->oldmask);
+    err |= __put_user(usp, &sc->usp); return err;
+}
+
+static inline unsigned long align_sigframe(unsigned long sp)
+{
+    unsigned long i;
+    i = sp & ~3UL;
+    return i;
+}
+
+static inline abi_ulong get_sigframe(struct target_sigaction *ka,
+                                     CPUOpenRISCState *regs,
+                                     size_t frame_size)
+{
+    unsigned long sp = regs->gpr[1];
+    int onsigstack = on_sig_stack(sp);
+
+    /* redzone */
+    /* This is the X/Open sanctioned signal stack switching.  */
+    if ((ka->sa_flags & SA_ONSTACK) != 0 && !onsigstack) {
+        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+    }
+
+    sp = align_sigframe(sp - frame_size);
+
+    /*
+     * If we are on the alternate signal stack and would overflow it, don't.
+     * Return an always-bogus address instead so we will die with SIGSEGV.
+     */
+
+    if (onsigstack && !likely(on_sig_stack(sp))) {
+        return -1L;
+    }
+
+    return sp;
+}
+
+static void setup_frame(int sig, struct target_sigaction *ka,
+                        target_sigset_t *set, CPUOpenRISCState *env)
+{
+    printf("Not implement.\n");
+}
+
+static void setup_rt_frame(int sig, struct target_sigaction *ka,
+                           target_siginfo_t *info,
+                           target_sigset_t *set, CPUOpenRISCState *env)
+{
+    int err = 0;
+    abi_ulong frame_addr;
+    unsigned long return_ip;
+    struct target_rt_sigframe *frame;
+    abi_ulong info_addr, uc_addr;
+
+    frame_addr = get_sigframe(ka, env, sizeof *frame);
+
+    frame_addr = get_sigframe(ka, env, sizeof(*frame));
+    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
+        goto give_sigsegv;
+    }
+
+    info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
+    err |= __put_user(info_addr, &frame->pinfo);
+    uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
+    err |= __put_user(uc_addr, &frame->puc);
+
+    if (ka->sa_flags & SA_SIGINFO) {
+        err |= copy_siginfo_to_user(&frame->info, info);
+    }
+    if (err) {
+        goto give_sigsegv;
+    }
+
+    /*err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));*/
+    err |= __put_user(0, &frame->uc.tuc_flags);
+    err |= __put_user(0, &frame->uc.tuc_link);
+    err |= __put_user(target_sigaltstack_used.ss_sp,
+                      &frame->uc.tuc_stack.ss_sp);
+    err |= __put_user(sas_ss_flags(env->gpr[1]), &frame->uc.tuc_stack.ss_flags);
+    err |= __put_user(target_sigaltstack_used.ss_size,
+                      &frame->uc.tuc_stack.ss_size);
+    err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
+
+    /*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
+
+    if (err) {
+        goto give_sigsegv;
+    }
+
+    /* trampoline - the desired return ip is the retcode itself */
+    return_ip = (unsigned long)&frame->retcode;
+    /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
+    err |= __put_user(0xa960, (short *)(frame->retcode + 0));
+    err |= __put_user(TARGET_NR_rt_sigreturn, (short *)(frame->retcode + 2));
+    err |= __put_user(0x20000001, (unsigned long *)(frame->retcode + 4));
+    err |= __put_user(0x15000000, (unsigned long *)(frame->retcode + 8));
+
+    if (err) {
+        goto give_sigsegv;
+    }
+
+    /* TODO what is the current->exec_domain stuff and invmap ? */
+
+    /* Set up registers for signal handler */
+    env->pc = (unsigned long)ka->_sa_handler; /* what we enter NOW */
+    env->gpr[9] = (unsigned long)return_ip;     /* what we enter LATER */
+    env->gpr[3] = (unsigned long)sig;           /* arg 1: signo */
+    env->gpr[4] = (unsigned long)&frame->info;  /* arg 2: (siginfo_t*) */
+    env->gpr[5] = (unsigned long)&frame->uc;    /* arg 3: ucontext */
+
+    /* actually move the usp to reflect the stacked frame */
+    env->gpr[1] = (unsigned long)frame;
+
+    return;
+
+give_sigsegv:
+    unlock_user_struct(frame, frame_addr, 1);
+    if (sig == TARGET_SIGSEGV) {
+        ka->_sa_handler = TARGET_SIG_DFL;
+    }
+    force_sig(TARGET_SIGSEGV);
+}
+
+long do_sigreturn(CPUOpenRISCState *env)
+{
+
+    fprintf(stderr, "do_sigreturn: not implemented\n");
+    return -TARGET_ENOSYS;
+}
+
+long do_rt_sigreturn(CPUOpenRISCState *env)
+{
+    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
+    return -TARGET_ENOSYS;
+}
+/* TARGET_OPENRISC */
+
 #elif defined(TARGET_S390X)
 
 #define __NUM_GPRS 16
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 539af3f..630a455 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7377,7 +7377,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_sigaltstack:
 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
     defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
-    defined(TARGET_M68K) || defined(TARGET_S390X)
+    defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
         ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
         break;
 #else
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index a79b67d..cfece21 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -59,7 +59,7 @@
 
 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \
     || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_UNICORE32) \
-    || defined(TARGET_S390X)
+    || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
 
 #define TARGET_IOC_SIZEBITS	14
 #define TARGET_IOC_DIRBITS	2
@@ -323,7 +323,7 @@ int do_sigaction(int sig, const struct target_sigaction *act,
     || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined(TARGET_SH4) \
     || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) \
     || defined(TARGET_MICROBLAZE) || defined(TARGET_UNICORE32) \
-    || defined(TARGET_S390X)
+    || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
 
 #if defined(TARGET_SPARC)
 #define TARGET_SA_NOCLDSTOP    8u
@@ -344,6 +344,14 @@ int do_sigaction(int sig, const struct target_sigaction *act,
 #if !defined(TARGET_ABI_MIPSN32) && !defined(TARGET_ABI_MIPSN64)
 #define TARGET_SA_RESTORER	0x04000000	/* Only for O32 */
 #endif
+#elif defined(TARGET_OPENRISC)
+#define TARGET_SA_NOCLDSTOP    0x00000001
+#define TARGET_SA_NOCLDWAIT    0x00000002
+#define TARGET_SA_SIGINFO      0x00000004
+#define TARGET_SA_ONSTACK      0x08000000
+#define TARGET_SA_RESTART      0x10000000
+#define TARGET_SA_NODEFER      0x40000000
+#define TARGET_SA_RESETHAND    0x80000000
 #elif defined(TARGET_ALPHA)
 #define TARGET_SA_ONSTACK	0x00000001
 #define TARGET_SA_RESTART	0x00000002
@@ -448,6 +456,7 @@ int do_sigaction(int sig, const struct target_sigaction *act,
 
 #else
 
+/* OpenRISC Using the general signals */
 #define TARGET_SIGHUP		 1
 #define TARGET_SIGINT		 2
 #define TARGET_SIGQUIT		 3
@@ -1086,7 +1095,8 @@ struct target_winsize {
 #endif
 
 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) \
-    || defined(TARGET_CRIS) || defined(TARGET_UNICORE32)
+    || defined(TARGET_CRIS) || defined(TARGET_UNICORE32) \
+    || defined(TARGET_OPENRISC)
 struct target_stat {
 	unsigned short st_dev;
 	unsigned short __pad1;
@@ -1783,6 +1793,30 @@ struct target_stat {
     abi_long       st_blocks;
     abi_ulong  __unused[3];
 };
+#elif defined(TARGET_OPENRISC)
+struct target_stat {
+    abi_ulong st_dev;
+    abi_ulong st_ino;
+    abi_ulong st_nlink;
+
+    unsigned int st_mode;
+    unsigned int st_uid;
+    unsigned int st_gid;
+    unsigned int __pad0;
+    abi_ulong st_rdev;
+    abi_long st_size;
+    abi_long st_blksize;
+    abi_long st_blocks;    /* Number 512-byte blocks allocated. */
+
+    abi_ulong target_st_atime;
+    abi_ulong target_st_atime_nsec;
+    abi_ulong target_st_mtime;
+    abi_ulong target_st_mtime_nsec;
+    abi_ulong target_st_ctime;
+    abi_ulong target_st_ctime_nsec;
+
+    abi_long __unused[3];
+};
 #else
 #error unsupported CPU
 #endif
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index d499dc4..34dd844 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -364,11 +364,13 @@ void do_interrupt(CPUOpenRISCState *env);
 void openrisc_translate_init(void);
 int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, target_ulong address,
                                   int rw, int mmu_idx);
+int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc);
 
 #define cpu_list cpu_openrisc_list
 #define cpu_exec cpu_openrisc_exec
 #define cpu_gen_code cpu_openrisc_gen_code
 #define cpu_handle_mmu_fault cpu_openrisc_handle_mmu_fault
+#define cpu_signal_handler cpu_openrisc_signal_handler
 
 #define CPU_SAVE_VERSION 1
 
@@ -400,6 +402,16 @@ static inline CPUOpenRISCState *cpu_init(const char *cpu_model)
     return NULL;
 }
 
+#if defined(CONFIG_USER_ONLY)
+static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->gpr[1] = newsp;
+    }
+    env->gpr[2] = 0;
+}
+#endif
+
 #include "cpu-all.h"
 
 static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
-- 
1.7.9.5

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

* [Qemu-devel] [PATCH v6 16/16] target-or32: Add testcases
  2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
                   ` (14 preceding siblings ...)
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 15/16] target-or32: Add linux user support Jia Liu
@ 2012-06-21  2:58 ` Jia Liu
  15 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  2:58 UTC (permalink / raw)
  To: qemu-devel

Add testcases for OpenRISC.

Signed-off-by: Jia Liu <proljc@gmail.com>
---
 tests/tcg/openrisc/Makefile      |   71 +++++++++++++++++++++++++++
 tests/tcg/openrisc/test_add.c    |   34 +++++++++++++
 tests/tcg/openrisc/test_addc.c   |   39 +++++++++++++++
 tests/tcg/openrisc/test_addi.c   |   31 ++++++++++++
 tests/tcg/openrisc/test_addic.c  |   33 +++++++++++++
 tests/tcg/openrisc/test_and_or.c |   61 +++++++++++++++++++++++
 tests/tcg/openrisc/test_bf.c     |   46 ++++++++++++++++++
 tests/tcg/openrisc/test_bnf.c    |   50 +++++++++++++++++++
 tests/tcg/openrisc/test_div.c    |   32 ++++++++++++
 tests/tcg/openrisc/test_divu.c   |   32 ++++++++++++
 tests/tcg/openrisc/test_extx.c   |   72 +++++++++++++++++++++++++++
 tests/tcg/openrisc/test_fx.c     |   53 ++++++++++++++++++++
 tests/tcg/openrisc/test_j.c      |   26 ++++++++++
 tests/tcg/openrisc/test_jal.c    |   26 ++++++++++
 tests/tcg/openrisc/test_lf_add.c |   39 +++++++++++++++
 tests/tcg/openrisc/test_lf_div.c |   34 +++++++++++++
 tests/tcg/openrisc/test_lf_eqs.c |   84 ++++++++++++++++++++++++++++++++
 tests/tcg/openrisc/test_lf_ges.c |   84 ++++++++++++++++++++++++++++++++
 tests/tcg/openrisc/test_lf_gts.c |   84 ++++++++++++++++++++++++++++++++
 tests/tcg/openrisc/test_lf_les.c |   84 ++++++++++++++++++++++++++++++++
 tests/tcg/openrisc/test_lf_lts.c |   91 ++++++++++++++++++++++++++++++++++
 tests/tcg/openrisc/test_lf_mul.c |   22 +++++++++
 tests/tcg/openrisc/test_lf_nes.c |   87 +++++++++++++++++++++++++++++++++
 tests/tcg/openrisc/test_lf_rem.c |   32 ++++++++++++
 tests/tcg/openrisc/test_lf_sub.c |   33 +++++++++++++
 tests/tcg/openrisc/test_logic.c  |  100 ++++++++++++++++++++++++++++++++++++++
 tests/tcg/openrisc/test_lx.c     |   78 +++++++++++++++++++++++++++++
 tests/tcg/openrisc/test_movhi.c  |   30 ++++++++++++
 tests/tcg/openrisc/test_mul.c    |   47 ++++++++++++++++++
 tests/tcg/openrisc/test_muli.c   |   47 ++++++++++++++++++
 tests/tcg/openrisc/test_mulu.c   |   47 ++++++++++++++++++
 tests/tcg/openrisc/test_sfeq.c   |   44 +++++++++++++++++
 tests/tcg/openrisc/test_sfeqi.c  |   39 +++++++++++++++
 tests/tcg/openrisc/test_sfges.c  |   44 +++++++++++++++++
 tests/tcg/openrisc/test_sfgesi.c |   40 +++++++++++++++
 tests/tcg/openrisc/test_sfgeu.c  |   44 +++++++++++++++++
 tests/tcg/openrisc/test_sfgeui.c |   41 ++++++++++++++++
 tests/tcg/openrisc/test_sfgts.c  |   45 +++++++++++++++++
 tests/tcg/openrisc/test_sfgtsi.c |   41 ++++++++++++++++
 tests/tcg/openrisc/test_sfgtu.c  |   43 ++++++++++++++++
 tests/tcg/openrisc/test_sfgtui.c |   42 ++++++++++++++++
 tests/tcg/openrisc/test_sfles.c  |   26 ++++++++++
 tests/tcg/openrisc/test_sflesi.c |   39 +++++++++++++++
 tests/tcg/openrisc/test_sfleu.c  |   43 ++++++++++++++++
 tests/tcg/openrisc/test_sfleui.c |   39 +++++++++++++++
 tests/tcg/openrisc/test_sflts.c  |   43 ++++++++++++++++
 tests/tcg/openrisc/test_sfltsi.c |   38 +++++++++++++++
 tests/tcg/openrisc/test_sfltu.c  |   41 ++++++++++++++++
 tests/tcg/openrisc/test_sfltui.c |   39 +++++++++++++++
 tests/tcg/openrisc/test_sfne.c   |   43 ++++++++++++++++
 tests/tcg/openrisc/test_sfnei.c  |   38 +++++++++++++++
 tests/tcg/openrisc/test_sub.c    |   34 +++++++++++++
 52 files changed, 2475 insertions(+)
 create mode 100644 tests/tcg/openrisc/Makefile
 create mode 100644 tests/tcg/openrisc/test_add.c
 create mode 100644 tests/tcg/openrisc/test_addc.c
 create mode 100644 tests/tcg/openrisc/test_addi.c
 create mode 100644 tests/tcg/openrisc/test_addic.c
 create mode 100644 tests/tcg/openrisc/test_and_or.c
 create mode 100644 tests/tcg/openrisc/test_bf.c
 create mode 100644 tests/tcg/openrisc/test_bnf.c
 create mode 100644 tests/tcg/openrisc/test_div.c
 create mode 100644 tests/tcg/openrisc/test_divu.c
 create mode 100644 tests/tcg/openrisc/test_extx.c
 create mode 100644 tests/tcg/openrisc/test_fx.c
 create mode 100644 tests/tcg/openrisc/test_j.c
 create mode 100644 tests/tcg/openrisc/test_jal.c
 create mode 100644 tests/tcg/openrisc/test_lf_add.c
 create mode 100644 tests/tcg/openrisc/test_lf_div.c
 create mode 100644 tests/tcg/openrisc/test_lf_eqs.c
 create mode 100644 tests/tcg/openrisc/test_lf_ges.c
 create mode 100644 tests/tcg/openrisc/test_lf_gts.c
 create mode 100644 tests/tcg/openrisc/test_lf_les.c
 create mode 100644 tests/tcg/openrisc/test_lf_lts.c
 create mode 100644 tests/tcg/openrisc/test_lf_mul.c
 create mode 100644 tests/tcg/openrisc/test_lf_nes.c
 create mode 100644 tests/tcg/openrisc/test_lf_rem.c
 create mode 100644 tests/tcg/openrisc/test_lf_sub.c
 create mode 100644 tests/tcg/openrisc/test_logic.c
 create mode 100644 tests/tcg/openrisc/test_lx.c
 create mode 100644 tests/tcg/openrisc/test_movhi.c
 create mode 100644 tests/tcg/openrisc/test_mul.c
 create mode 100644 tests/tcg/openrisc/test_muli.c
 create mode 100644 tests/tcg/openrisc/test_mulu.c
 create mode 100644 tests/tcg/openrisc/test_sfeq.c
 create mode 100644 tests/tcg/openrisc/test_sfeqi.c
 create mode 100644 tests/tcg/openrisc/test_sfges.c
 create mode 100644 tests/tcg/openrisc/test_sfgesi.c
 create mode 100644 tests/tcg/openrisc/test_sfgeu.c
 create mode 100644 tests/tcg/openrisc/test_sfgeui.c
 create mode 100644 tests/tcg/openrisc/test_sfgts.c
 create mode 100644 tests/tcg/openrisc/test_sfgtsi.c
 create mode 100644 tests/tcg/openrisc/test_sfgtu.c
 create mode 100644 tests/tcg/openrisc/test_sfgtui.c
 create mode 100644 tests/tcg/openrisc/test_sfles.c
 create mode 100644 tests/tcg/openrisc/test_sflesi.c
 create mode 100644 tests/tcg/openrisc/test_sfleu.c
 create mode 100644 tests/tcg/openrisc/test_sfleui.c
 create mode 100644 tests/tcg/openrisc/test_sflts.c
 create mode 100644 tests/tcg/openrisc/test_sfltsi.c
 create mode 100644 tests/tcg/openrisc/test_sfltu.c
 create mode 100644 tests/tcg/openrisc/test_sfltui.c
 create mode 100644 tests/tcg/openrisc/test_sfne.c
 create mode 100644 tests/tcg/openrisc/test_sfnei.c
 create mode 100644 tests/tcg/openrisc/test_sub.c

diff --git a/tests/tcg/openrisc/Makefile b/tests/tcg/openrisc/Makefile
new file mode 100644
index 0000000..92d4fb7
--- /dev/null
+++ b/tests/tcg/openrisc/Makefile
@@ -0,0 +1,71 @@
+-include ../../config-host.mak
+
+CROSS = or32-linux-
+
+SIM = qemu-or32
+
+CC = $(CROSS)gcc
+
+TESTCASES = test_add.tst
+TESTCASES = test_sub.tst
+TESTCASES += test_addc.tst
+TESTCASES += test_addi.tst
+TESTCASES += test_addic.tst
+TESTCASES += test_and_or.tst
+TESTCASES += test_bf.tst
+TESTCASES += test_bnf.tst
+TESTCASES += test_div.tst
+TESTCASES += test_divu.tst
+TESTCASES += test_extx.tst
+TESTCASES += test_fx.tst
+TESTCASES += test_jal.tst
+TESTCASES += test_j.tst
+TESTCASES += test_lf_div.tst
+TESTCASES += test_lf_eqs.tst
+TESTCASES += test_lf_ges.tst
+TESTCASES += test_lf_gts.tst
+TESTCASES += test_lf_les.tst
+TESTCASES += test_lf_lts.tst
+TESTCASES += test_lf_mul.tst
+TESTCASES += test_lf_nes.tst
+TESTCASES += test_lf_rem.tst
+TESTCASES += test_lf_sub.tst
+TESTCASES += test_lf_add.tst
+TESTCASES += test_logic.tst
+TESTCASES += test_lx.tst
+TESTCASES += test_movhi.tst
+TESTCASES += test_mul.tst
+TESTCASES += test_mulu.tst
+TESTCASES += test_muli.tst
+TESTCASES += test_sfeq.tst
+TESTCASES += test_sfeqi.tst
+TESTCASES += test_sfges.tst
+TESTCASES += test_sfgesi.tst
+TESTCASES += test_sfgeu.tst
+TESTCASES += test_sfgeui.tst
+TESTCASES += test_sfgts.tst
+TESTCASES += test_sfgtsi.tst
+TESTCASES += test_sfgtu.tst
+TESTCASES += test_sfgtui.tst
+TESTCASES += test_sfles.tst
+TESTCASES += test_sflesi.tst
+TESTCASES += test_sfleu.tst
+TESTCASES += test_sfleui.tst
+TESTCASES += test_sflts.tst
+TESTCASES += test_sfltsi.tst
+TESTCASES += test_sfltu.tst
+TESTCASES += test_sfltui.tst
+TESTCASES += test_sfne.tst
+TESTCASES += test_sfnei.tst
+
+all: $(TESTCASES)
+
+%.tst: %.c
+	$(CC) -static $< -o $@
+
+
+check: $(TESTCASES)
+	@for case in $(TESTCASES); do $(SIM) $$case; echo $$case pass!; sleep 0.2; done
+
+clean:
+	$(RM) -rf $(TESTCASES)
diff --git a/tests/tcg/openrisc/test_add.c b/tests/tcg/openrisc/test_add.c
new file mode 100644
index 0000000..8845257
--- /dev/null
+++ b/tests/tcg/openrisc/test_add.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0x100;
+    b = 0x100;
+    result = 0x200;
+
+    __asm
+    ("l.add %0, %0, %1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("add error\n");
+    }
+
+    a = 0xffff;
+    b = 0x1;
+    result = 0x10000;
+    __asm
+    ("l.add %0, %0, %1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("add error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_addc.c b/tests/tcg/openrisc/test_addc.c
new file mode 100644
index 0000000..40b7f93
--- /dev/null
+++ b/tests/tcg/openrisc/test_addc.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x01;
+    c = 0xffffffff;
+    result = 1;
+
+    __asm
+    ("l.addc   %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+
+    if (a != result) {
+        printf("first addc error\n");
+    }
+
+    b = 0x01;
+    c = 0xffffffff;
+    result = 0x80000001;
+    __asm
+    ("l.addc   %0, %1, %2\n\t"
+     "l.movhi  %2, 0x7fff\n\t"
+     "l.ori    %2, %2, 0xffff\n\t"
+     "l.addc   %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+
+    if (a != result) {
+        printf("addc error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_addi.c b/tests/tcg/openrisc/test_addi.c
new file mode 100644
index 0000000..4ee71f1
--- /dev/null
+++ b/tests/tcg/openrisc/test_addi.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    b = 0x01;
+    result = 0x00;
+    __asm
+    ("l.addi  %0, %1, 0xffff\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("addi error\n\t");
+    }
+
+    b = 0x010000;
+    result = 0xffff;
+    __asm
+    ("l.addi  %0, %1, 0xffff\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("addi error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_addic.c b/tests/tcg/openrisc/test_addic.c
new file mode 100644
index 0000000..b180aad
--- /dev/null
+++ b/tests/tcg/openrisc/test_addic.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    a = 1;
+    result = 0x1;
+
+    __asm
+    ("l.addic %0, %0, 0xffff\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("first addic error\n");
+    }
+
+    a = 0x1;
+    result = 0x201;
+    __asm
+    ("l.addic %0, %0, 0xffff\n\t"
+     "l.ori   %0, r0, 0x100\n\t"
+     "l.addic %0, %0, 0x100\n\t"
+     : "+r"(a)
+    );
+
+    if (a != result) {
+        printf("second addic error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_and_or.c b/tests/tcg/openrisc/test_and_or.c
new file mode 100644
index 0000000..e6f8828
--- /dev/null
+++ b/tests/tcg/openrisc/test_and_or.c
@@ -0,0 +1,61 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x2;
+    c = 0x1;
+    result = 0;
+
+    __asm
+    ("l.and  %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("and error\n");
+    }
+
+    result = 0x2;
+    __asm
+    ("l.andi  %0, %1, 0x3\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("andi error %x\n", a);
+    }
+
+    result = 0x3;
+    __asm
+    ("l.or   %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("or error\n");
+    }
+
+    result = 0x3;
+    __asm
+    ("l.xor  %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("xor error\n");
+    }
+
+    __asm
+    ("l.xori  %0, %1, 0x1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("xori error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_bf.c b/tests/tcg/openrisc/test_bf.c
new file mode 100644
index 0000000..53ea96d
--- /dev/null
+++ b/tests/tcg/openrisc/test_bf.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    a = 0;
+    b = 10;
+    c = 11;
+    result = 0x2;
+
+    __asm
+    ("1:\n\t"
+     "l.addi %1, %1, 0x01\n\t"
+     "l.addi %0, %0, 0x01\n\t"
+     "l.sfeq %1, %2\n\t"
+     "l.bf   1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sfeq error\n");
+    }
+
+    a = 0x00;
+    b = 0x11;
+    c = 0x11;
+    result = 0x01;
+    __asm
+    ("1:\n\t"
+     "l.addi %1, %1, 0x01\n\t"
+     "l.addi %0, %0, 0x01\n\t"
+     "l.sfeq %1, %2\n\t"
+     "l.bf   1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sfeq error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_bnf.c b/tests/tcg/openrisc/test_bnf.c
new file mode 100644
index 0000000..bca94d9
--- /dev/null
+++ b/tests/tcg/openrisc/test_bnf.c
@@ -0,0 +1,50 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    b = 0;
+    result = 0x3;
+
+    __asm
+    ("l.sfeqi %1, 0x0\n\t"
+     "l.bnf 1f\n\t"
+     "l.nop\n\t"
+     "\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     "\n\t"
+     "1:\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("l.bnf error\n");
+    }
+
+    a = 0;
+    b = 0;
+    result = 1;
+    __asm
+    ("l.sfeqi %1, 0x1\n\t"
+     "l.bnf 1f\n\t"
+     "l.nop\n\t"
+     "\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     "\n\t"
+     "1:\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("l.bnf error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_div.c b/tests/tcg/openrisc/test_div.c
new file mode 100644
index 0000000..2bd285b
--- /dev/null
+++ b/tests/tcg/openrisc/test_div.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x120;
+    c = 0x4;
+    result = 0x48;
+
+    __asm
+    ("l.div  %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("div error\n");
+    }
+
+    result = 0x4;
+    __asm
+    ("l.div %0, %1, %0\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("div error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_divu.c b/tests/tcg/openrisc/test_divu.c
new file mode 100644
index 0000000..da8aad3
--- /dev/null
+++ b/tests/tcg/openrisc/test_divu.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x120;
+    c = 0x4;
+    result = 0x48;
+
+    __asm
+    ("l.divu  %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("divu error\n");
+    }
+
+    result = 0x4;
+    __asm
+    ("l.divu %0, %1, %0\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("divu error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_extx.c b/tests/tcg/openrisc/test_extx.c
new file mode 100644
index 0000000..08e5083
--- /dev/null
+++ b/tests/tcg/openrisc/test_extx.c
@@ -0,0 +1,72 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    b = 0x83;
+    result = 0xffffff83;
+    __asm
+    ("l.extbs  %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("extbs error\n");
+    }
+
+    result = 0x83;
+    __asm
+    ("l.extbz  %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("extbz error\n");
+    }
+
+    b = 0x8083;
+    result = 0xffff8083;
+    __asm
+    ("l.exths  %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("exths error\n");
+    }
+
+    result = 0x8083;
+    __asm
+    ("l.exthz  %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("exthz error\n");
+    }
+
+    b = 0x11;
+    result = 0x11;
+    __asm
+    ("l.extws  %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+
+    if (a != result) {
+        printf("extws error\n");
+    }
+
+    __asm
+    ("l.extwz  %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("extwz error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_fx.c b/tests/tcg/openrisc/test_fx.c
new file mode 100644
index 0000000..238817e
--- /dev/null
+++ b/tests/tcg/openrisc/test_fx.c
@@ -0,0 +1,53 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    b = 0x123;
+    result = 1;
+    __asm
+    ("l.ff1 %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("ff1 error\n");
+    }
+
+    b = 0x0;
+    result = 0;
+    __asm
+    ("l.ff1 %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("ff1 error\n");
+    }
+
+    b = 0x123;
+    result = 9;
+    __asm
+    ("l.fl1 %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("fl1 error\n");
+    }
+
+    b = 0x0;
+    result = 0;
+    __asm
+    ("l.fl1 %0, %1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("fl1 error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_j.c b/tests/tcg/openrisc/test_j.c
new file mode 100644
index 0000000..183d051
--- /dev/null
+++ b/tests/tcg/openrisc/test_j.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 2;
+
+    __asm
+    ("l.addi %0, %0, 1\n\t"
+     "l.j j\n\t"
+     "l.nop\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "l.nop\n\t"
+     "j:\n\t"
+     "l.addi %0, %0, 1\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("j error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_jal.c b/tests/tcg/openrisc/test_jal.c
new file mode 100644
index 0000000..4c9af9a
--- /dev/null
+++ b/tests/tcg/openrisc/test_jal.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 2;
+
+    __asm
+    ("l.addi %0, %0, 1\n\t"
+     "l.jal jal\n\t"
+     "l.nop\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "l.nop\n\t"
+     "jal:\n\t"
+     "l.addi %0, %0, 1\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("jal error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_add.c b/tests/tcg/openrisc/test_lf_add.c
new file mode 100644
index 0000000..212b135
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_add.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int main(void)
+{
+    float a, b;
+    float res2;
+    a = 1.5;
+    b = 2.5;
+    res2 = 4.0;
+
+    __asm
+    ("lf.add.s  %0, %0, %1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+
+    if (a != res2) {
+        printf("lf.add.s error, %f\n", a);
+    }
+
+/*    double c, d;
+    double res1;
+
+    c = 1.5;
+    d = 1.5;
+    res1 = 3.00;
+
+    __asm
+    ("lf.add.d  %0, %1, %2\n\t"
+     : "+r"(c)
+     : "r"(d)
+    );
+
+    if ((e - res1) > 0.002) {
+        printf("lf.add.d error, %f\n", e - res1);
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_div.c b/tests/tcg/openrisc/test_lf_div.c
new file mode 100644
index 0000000..c090ec6
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_div.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+
+int main(void)
+{
+    float a, b, c;
+    float result;
+    b = 1.5;
+    c = 0.5;
+    result = 3.0;
+    __asm
+    ("lf.div.s    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.div.s error\n");
+    }
+
+/*    double a, b, c, res;
+
+    b = 0x80000000;
+    c = 0x40;
+    result = 0x2000000;
+    __asm
+    ("lf.div.d    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.div.d error\n");
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_eqs.c b/tests/tcg/openrisc/test_lf_eqs.c
new file mode 100644
index 0000000..57bb779
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_eqs.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, result;
+    float b, c;
+
+    a = 0x1;
+    b = 122.5;
+    c = 123.5;
+    result = 0x3;
+    __asm
+    ("lfeqd:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfeq.s %1, %2\n\t"
+     "l.bf      lfeqd\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfeq.s error\n");
+    }
+
+    b = 13.5;
+    c = 13.5;
+    result = 0x3;
+    __asm
+    ("lf.sfeq.s %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    r4, r4, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfeq.s error\n");
+    }
+
+/*    double b, c;
+    double result;
+    int a;
+
+    a = 0x1;
+    b = 122.5;
+    c = 133.5;
+    result = 0x3;
+
+    __asm
+    ("lfeqd:\n\t"
+     "l.addi %0, %0, 0x1\n\t"
+     "lf.sfeq.d %1, %2\n\t"
+     "l.bf      lfeqd\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfeq.d error\n");
+    }
+
+    double c, d, res;
+    int e = 0;
+    c = 11.5;
+    d = 11.5;
+    res = 1;
+    __asm
+    ("lf.sfeq.d %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(e)
+     : "r"(c), "r"(d)
+    );
+    if (e != res) {
+        printf("lf.sfeq.d error\n");
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_ges.c b/tests/tcg/openrisc/test_lf_ges.c
new file mode 100644
index 0000000..935c137
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_ges.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, result;
+    float b, c;
+
+    a = 0;
+    b = 122.5;
+    c = 123.5;
+    result = 0x1;
+    __asm
+    ("lfges:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfge.s %1, %2\n\t"
+     "l.bf      lfges\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfge.s error\n");
+    }
+
+    b = 133.5;
+    c = 13.5;
+    result = 0x3;
+    __asm
+    ("l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfge.s %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfge.s error\n");
+    }
+
+/*    int a, result;
+    double b, c;
+
+    a = 0x1;
+    b = 122.5;
+    c = 123.5;
+    result = 0x2;
+    __asm
+    ("lfged:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfge.d %1, %2\n\t"
+     "l.bf      lfged\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfge.d error\n");
+    }
+
+    b = 133.5;
+    c = 13.5;
+    result = 0x4;
+    __asm
+    ("lf.sfge.d %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfge.d error\n");
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_gts.c b/tests/tcg/openrisc/test_lf_gts.c
new file mode 100644
index 0000000..166a0bf
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_gts.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, result;
+    float b, c;
+
+    a = 0;
+    b = 122.5;
+    c = 123.5;
+    result = 0x1;
+
+    __asm
+    ("lfgts:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfgt.s %1, %2\n\t"
+     "l.bf      lfgts\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfgt.s error\n");
+    }
+
+    b = 133.5;
+    c = 13.5;
+    result = 0x1;
+
+    __asm
+    ("lf.sfgt.s %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfgt.s error\n");
+    }
+
+/*    int a, result;
+    double b, c;
+
+    a = 0;
+    b = 122.5;
+    c = 123.5;
+    result = 0x1;
+    __asm
+    ("lfgtd:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfgt.d %1, %2\n\t"
+     "l.bf      lfgtd\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfgt.d error\n");
+    }
+
+    b = 133.5;
+    c = 13.5;
+    result = 0x3;
+    __asm
+    ("l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfgt.d %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfgt.d error, %x\n", a);
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_les.c b/tests/tcg/openrisc/test_lf_les.c
new file mode 100644
index 0000000..5e648ec
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_les.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    float b, c;
+    int result;
+
+    a = 0;
+    b = 1234.2;
+    c = 12.4;
+    result = 0x1;
+    __asm
+    ("lfles:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfle.s %1, %2\n\t"
+     "l.bf      lfles\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfle.s error\n");
+    }
+
+    b = 1.1;
+    c = 19.4;
+    result = 0x3;
+    __asm
+    ("l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfle.s %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfle.s error\n");
+    }
+
+/*    int a;
+    double b, c;
+    int result;
+
+    a = 0;
+    b = 1212.5;
+    c = 123.5;
+    result = 0x1;
+    __asm
+    ("lfled:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfle.d %1, %2\n\t"
+     "l.bf      lfled\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfle.d error\n");
+    }
+
+    b = 13.5;
+    c = 113.5;
+    result = 0x2;
+    __asm
+    ("l.addi    %0, %0, 0x1\n\t"
+     "lf.sfle.d %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfle.d error\n");
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_lts.c b/tests/tcg/openrisc/test_lf_lts.c
new file mode 100644
index 0000000..0424bb4
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_lts.c
@@ -0,0 +1,91 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    float b, c, d;
+    int result;
+
+    a = 0;
+    b = 124.5;
+    c = 1.4;
+    result = 1;
+
+    __asm
+    ("lfltd:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sflt.s %1, %2\n\t"
+     "l.bf      lfltd\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sflt.s error\n");
+    }
+
+    a = 0;
+    b = 11.1;
+    c = 13.1;
+    d = 1.0;
+    result = 2;
+
+    __asm
+    ("1:\n\t"
+     "lf.add.s  %1, %1, %3\n\t"
+     "l.addi    %0, %0, 1\n\t"
+     "lf.sflt.s %1, %2\n\t"
+     "l.bf      1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c), "r"(d)
+    );
+    if (a != result) {
+        printf("lf.sflt.s error\n");
+    }
+
+/*    int a;
+    double b, c;
+    int result;
+
+    a = 0;
+    b = 1432.1;
+    c = 2.4;
+    result = 0x1;
+
+    __asm
+    ("lfltd:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sflt.d %1, %2\n\t"
+     "l.bf      lfltd\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sflt.d error\n");
+    }
+
+    a = 0;
+    b = 1.1;
+    c = 19.7;
+    result = 2;
+    __asm
+    ("lf.sflt.d %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "1:\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "l.addi %0, %0, 1\n\t"
+     : "+r"(a), "+r"(b)
+     : "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sflt.d error\n");
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_mul.c b/tests/tcg/openrisc/test_lf_mul.c
new file mode 100644
index 0000000..1cffadb
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_mul.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+int main(void)
+{
+    float a, b, c;
+    float result;
+
+    b = 1.5;
+    c = 4.0;
+    result = 6.0;
+
+    __asm
+    ("lf.mul.s   %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.mul.s error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_nes.c b/tests/tcg/openrisc/test_lf_nes.c
new file mode 100644
index 0000000..e66409d
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_nes.c
@@ -0,0 +1,87 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    float b, c;
+    int result;
+
+    a = 0;
+    b = 23.1;
+    c = 23.1;
+    result = 0x1;
+
+    __asm
+    ("lfnes:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfne.s %1, %2\n\t"
+     "l.bf      lfnes\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfne.s error");
+    }
+
+    b = 12.4;
+    c = 7.8;
+    result = 0x3;
+    __asm
+    ("l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfne.s %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfne.s error\n");
+    }
+/*    int a;
+    double b, c;
+    int result;
+
+    a = 0;
+    b = 124.3;
+    c = 124.3;
+    result = 0x1;
+    __asm
+    ("lfned:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfne.d %1, %2\n\t"
+     "l.bf      lfned\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfne.d error\n");
+    }
+
+    b = 11.5;
+    c = 16.7;
+    result = 0x3;
+
+    __asm
+    ("l.addi    %0, %0, 0x1\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "lf.sfne.d %1, %2\n\t"
+     "l.bf      1f\n\t"
+     "l.nop\n\t"
+     "l.addi    r4, r4, 0x1\n\t"
+     "l.addi    r4, r4, 0x1\n\t"
+     "1:\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sfne.d error\n");
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_rem.c b/tests/tcg/openrisc/test_lf_rem.c
new file mode 100644
index 0000000..4662c49
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_rem.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+
+int main(void)
+{
+    float a, b, c;
+    float result;
+
+    b = 101.5;
+    c = 10;
+    result = 1.5;
+
+/*    __asm
+    ("lf.rem.d      %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.rem.d error\n");
+    }*/
+
+    __asm
+    ("lf.rem.s      %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+
+    if (a != result) {
+        printf("lf.rem.s error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lf_sub.c b/tests/tcg/openrisc/test_lf_sub.c
new file mode 100644
index 0000000..c29a522
--- /dev/null
+++ b/tests/tcg/openrisc/test_lf_sub.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+int main(void)
+{
+    float a, b, c;
+    float result;
+    b = 10.5;
+    c = 1.5;
+    result = 9.0;
+    __asm
+    ("lf.sub.s  %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sub.s error\n");
+    }
+
+/*    b = 0x999;
+    c = 0x654;
+    result = 0x345;
+
+    __asm
+    ("lf.sub.d  %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("lf.sub.d error\n");
+    }*/
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_logic.c b/tests/tcg/openrisc/test_logic.c
new file mode 100644
index 0000000..a01461b
--- /dev/null
+++ b/tests/tcg/openrisc/test_logic.c
@@ -0,0 +1,100 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x9743;
+    c = 0x2;
+    result = 0x25d0c;
+
+    __asm
+    ("l.sll    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sll error\n");
+    }
+
+    b = 0x9743;
+    result = 0x25d0c;
+    __asm
+    ("l.slli   %0, %1, 0x2\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("slli error\n");
+    }
+
+    b = 0x7654;
+    c = 0x03;
+    result = 0xeca;
+    __asm
+    ("l.srl    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+
+    b = 0x7654;
+    result = 0xeca;
+    __asm
+    ("l.srli   %0, %1, 0x3\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("srli error\n");
+    }
+
+    b = 0x80000001;
+    c = 0x4;
+    result = 0x18000000;
+    __asm
+    ("l.ror    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("ror error\n");
+    }
+
+    b = 0x80000001;
+    result = 0x18000000;
+    __asm
+    ("l.rori   %0, %1, 0x4\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("rori error\n");
+    }
+
+    b = 0x80000001;
+    c = 0x03;
+    result = 0xf0000000;
+    __asm
+    ("l.sra    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sra error\n");
+    }
+
+    b = 0x80000001;
+    result = 0xf0000000;
+
+    __asm
+    ("l.srai   %0, %1, 0x3\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("srai error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_lx.c b/tests/tcg/openrisc/test_lx.c
new file mode 100644
index 0000000..854deef
--- /dev/null
+++ b/tests/tcg/openrisc/test_lx.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int p[50];
+    int result;
+
+    result = 0x23;
+    __asm
+    ("l.ori r8, r0, 0x123\n\t"
+     "l.sb  0x4 + %1, r8\n\t"
+     "\n\t"
+     "l.lbz %0, 0x4 + %1\n\t"
+     : "=r"(a), "+m"(*p)
+    );
+    if (a != result) {
+        printf("lbz error, %x\n", a);
+    }
+
+    result = 0x23;
+    __asm
+    ("l.lbs %0, 0x4 + %1\n\t"
+     : "=r"(a)
+     : "m"(*p)
+    );
+    if (a != result) {
+        printf("lbs error\n");
+    }
+
+    result = 0x1111;
+    __asm
+    ("l.ori r8, r0, 0x1111\n\t"
+     "l.sh  0x20 + %1, r8\n\t"
+     "\n\t"
+     "l.lhs %0, 0x20 + %1\n\t"
+     : "=r"(a), "=m"(*p)
+    );
+    if (a != result) {
+        printf("lhs error, %x\n", a);
+    }
+
+    result = 0x1111;
+    __asm
+    ("l.lhz %0, 0x20 + %1\n\t"
+     : "=r"(a)
+     : "m"(*p)
+    );
+    if (a != result) {
+        printf("lhz error\n");
+    }
+
+    result = 0x1111233;
+    __asm
+    ("l.ori r8, r0, 0x1233\n\t"
+     "l.movhi r1, 0x111\n\t"
+     "l.or  r8, r8, r1\n\t"
+     "l.sw  0x123 + %1, r8\n\t"
+     "\n\t"
+     "l.lws %0, 0x123 + %1\n\t"
+     : "=r"(a), "+m"(*p)
+    );
+    if (a != result) {
+        printf("lws error, %x\n", a);
+    }
+
+    result = 0x1111233;
+    __asm
+    ("l.lwz %0, 0x123 + %1\n\t"
+     : "=r"(a)
+     : "m"(*p)
+    );
+    if (a != result) {
+        printf("lwz error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_movhi.c b/tests/tcg/openrisc/test_movhi.c
new file mode 100644
index 0000000..9548a7a
--- /dev/null
+++ b/tests/tcg/openrisc/test_movhi.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    result = 0x1222;
+
+    __asm
+    ("l.movhi r3, 0x1222\n\t"
+     "l.srli   %0, r3, 16\n\t"
+     : "=r"(a)
+    );
+    if (a != result) {
+        printf("movhi error\n");
+    }
+
+    result = 0x1111;
+    __asm
+    ("l.movhi r8, 0x1111\n\t"
+     "l.srli   %0, r8, 16\n\t"
+     : "=r"(a)
+    );
+    if (a != result) {
+        printf("movhi error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_mul.c b/tests/tcg/openrisc/test_mul.c
new file mode 100644
index 0000000..d992d98
--- /dev/null
+++ b/tests/tcg/openrisc/test_mul.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x4;
+    c = 0x1;
+    result = 0x4;
+
+    __asm
+    ("l.mul    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("mul error\n");
+    }
+
+    b = 0x1;
+    c = 0x0;
+    result = 0x0;
+
+    __asm
+    ("l.mul    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("mul error\n");
+    }
+
+    b = 0x1;
+    c = 0xff;
+    result = 0xff;
+    __asm
+    ("l.mul    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("mul error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_muli.c b/tests/tcg/openrisc/test_muli.c
new file mode 100644
index 0000000..8630711
--- /dev/null
+++ b/tests/tcg/openrisc/test_muli.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x4;
+    c = 0x1;
+    result = 0x4;
+
+    __asm
+    ("l.muli    %0, %1, 0x1\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("muli error\n");
+    }
+
+    b = 0x1;
+    c = 0x0;
+    result = 0x0;
+
+    __asm
+    ("l.muli    %0, %1, 0x0\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("muli error\n");
+    }
+
+    b = 0x1;
+    c = 0xff;
+    result = 0xff;
+    __asm
+    ("l.muli    %0, %1, 0xff\n\t"
+     : "=r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("muli error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_mulu.c b/tests/tcg/openrisc/test_mulu.c
new file mode 100644
index 0000000..a62caff
--- /dev/null
+++ b/tests/tcg/openrisc/test_mulu.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    b = 0x4;
+    c = 0x1;
+    result = 0x4;
+
+    __asm
+    ("l.mulu    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("mulu error\n");
+    }
+
+    b = 0x1;
+    c = 0x0;
+    result = 0x0;
+
+    __asm
+    ("l.mulu    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("mulu error\n");
+    }
+
+    b = 0x1;
+    c = 0xff;
+    result = 0xff;
+    __asm
+    ("l.mulu    %0, %1, %2\n\t"
+     : "=r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("mulu error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfeq.c b/tests/tcg/openrisc/test_sfeq.c
new file mode 100644
index 0000000..52577fa
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfeq.c
@@ -0,0 +1,44 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0x1;
+    b = 0x80;
+    result = 0x2;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 0x1\n\t"
+     "l.sfeq   %0, %1\n\t"
+     "l.bf     1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfeq error\n");
+    }
+
+    a = 0x7f;
+    b = 0x80;
+    result = 0x81;
+
+    __asm
+    ("2:\n\t"
+     "l.addi   %0, %0, 0x1\n\t"
+     "l.sfeq   %0, %1\n\t"
+     "l.bf     2b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+
+    if (a != result) {
+        printf("sfeq error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfeqi.c b/tests/tcg/openrisc/test_sfeqi.c
new file mode 100644
index 0000000..6c9690d
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfeqi.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 1;
+    result = 2;
+
+    __asm
+    ("1:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.sfeqi   %0, 0x80\n\t"
+     "l.bf      1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfeqi error\n");
+    }
+
+    a = 0x7f;
+    result = 0x81;
+
+    __asm
+    ("2:\n\t"
+     "l.addi    %0, %0, 0x1\n\t"
+     "l.sfeqi   %0, 0x80\n\t"
+     "l.bf      2b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfeqi error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfges.c b/tests/tcg/openrisc/test_sfges.c
new file mode 100644
index 0000000..3505002
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfges.c
@@ -0,0 +1,44 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 1;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfges  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfges error\n");
+    }
+
+    a = 0xff;
+    b = 3;
+    c = 0x1;
+    result = 2;
+
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %2\n\t"
+     "l.sfges  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sfges error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgesi.c b/tests/tcg/openrisc/test_sfgesi.c
new file mode 100644
index 0000000..5c2bc8a
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgesi.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    result = 1;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfgesi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfgesi error\n");
+    }
+
+    a = 0xff;
+    b = 1;
+    result = 2;
+
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %1\n\t"
+     "l.sfgesi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgesi error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgeu.c b/tests/tcg/openrisc/test_sfgeu.c
new file mode 100644
index 0000000..c084c5f
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgeu.c
@@ -0,0 +1,44 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 1;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfgeu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgeu error\n");
+    }
+
+    a = 0xff;
+    b = 3;
+    c = 1;
+    result = 2;
+
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %2\n\t"
+     "l.sfgeu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sfgeu error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgeui.c b/tests/tcg/openrisc/test_sfgeui.c
new file mode 100644
index 0000000..ac4bd7f
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgeui.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    result = 1;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfgeui %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfgeui error\n");
+    }
+
+    a = 0xff;
+    b = 1;
+    result = 2;
+
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %1\n\t"
+     "l.sfgeui %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgeui error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgts.c b/tests/tcg/openrisc/test_sfgts.c
new file mode 100644
index 0000000..d2aeb0a
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgts.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 1;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfgts  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgts error\n");
+    }
+
+
+    a = 0xff;
+    b = 3;
+    c = 1;
+    result = 3;
+
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %2\n\t"
+     "l.sfgts  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sfgts error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgtsi.c b/tests/tcg/openrisc/test_sfgtsi.c
new file mode 100644
index 0000000..4ad398c
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgtsi.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    result = 1;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfgtsi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfgtsi error\n");
+    }
+
+    a = 0xff;
+    b = 1;
+    result = 3;
+
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %1\n\t"
+     "l.sfgtsi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgtsi error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgtu.c b/tests/tcg/openrisc/test_sfgtu.c
new file mode 100644
index 0000000..8a2b909
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgtu.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+int main(void)
+{
+    int a, b, c;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 1;
+
+    __asm
+    ("1:\n\t"
+     "l.addi %0, %0, 1\n\t"
+     "l.sfgtu %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgtu error\n");
+    }
+
+    a = 0xff;
+    b = 3;
+    c = 1;
+    result = 3;
+
+    __asm
+    ("1:\n\t"
+     "l.sub    %0, %0, %2\n\t"
+     "l.sfgtu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b), "r"(c)
+    );
+    if (a != result) {
+        printf("sfgtu error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfgtui.c b/tests/tcg/openrisc/test_sfgtui.c
new file mode 100644
index 0000000..755907a
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfgtui.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    result = 1;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfgtui %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfgtui error\n");
+    }
+
+
+    a = 0xff;
+    b = 1;
+    result = 3;
+
+    __asm
+    ("1:\n\t"
+     "l.sub     %0, %0, %1\n\t"
+     "l.sfgtui  %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfgtui error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfles.c b/tests/tcg/openrisc/test_sfles.c
new file mode 100644
index 0000000..3215936
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfles.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 4;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sfles  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfles error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sflesi.c b/tests/tcg/openrisc/test_sflesi.c
new file mode 100644
index 0000000..5ae6585
--- /dev/null
+++ b/tests/tcg/openrisc/test_sflesi.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 4;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sflesi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sflesi error\n");
+    }
+
+    a = 0;
+    result = 4;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sflesi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sflesi error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfleu.c b/tests/tcg/openrisc/test_sfleu.c
new file mode 100644
index 0000000..59fdaf7
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfleu.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 4;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sfleu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfleu error\n");
+    }
+
+    a = 0;
+    b = 3;
+    result = 4;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfleu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfleu error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfleui.c b/tests/tcg/openrisc/test_sfleui.c
new file mode 100644
index 0000000..df1ba07
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfleui.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 4;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sfleui %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfleui error\n");
+    }
+
+    a = 0;
+    result = 4;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfleui %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfleui error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sflts.c b/tests/tcg/openrisc/test_sflts.c
new file mode 100644
index 0000000..e4134ea
--- /dev/null
+++ b/tests/tcg/openrisc/test_sflts.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 4;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sflts  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sflts error\n");
+    }
+
+    a = 0;
+    b = 3;
+    result = 3;
+
+    __asm
+    ("1:\n\t"
+     "l.addi    %0, %0, 1\n\t"
+     "l.sflts   %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sflts error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfltsi.c b/tests/tcg/openrisc/test_sfltsi.c
new file mode 100644
index 0000000..68c2d79
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfltsi.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 4;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sfltsi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfltsi error\n");
+    }
+
+    a = 0;
+    result = 3;
+
+    __asm
+    ("1:\n\t"
+     "l.addi    %0, %0, 1\n\t"
+     "l.sfltsi  %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfltsi error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfltu.c b/tests/tcg/openrisc/test_sfltu.c
new file mode 100644
index 0000000..2b50c9c
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfltu.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 4;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sfltu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfltu error\n");
+    }
+
+    a = 0;
+    b = 3;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.addi    %0, %0, 1\n\t"
+     "l.sfltu  %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfltu error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfltui.c b/tests/tcg/openrisc/test_sfltui.c
new file mode 100644
index 0000000..8660d8f
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfltui.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 4;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 4\n\t"
+     "l.sfltsi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfltui error\n");
+    }
+
+    a = 0;
+    result = 3;
+
+    __asm
+    ("1:\n\t"
+     "l.addi    %0, %0, 1\n\t"
+     "l.sfltsi %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfltui error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfne.c b/tests/tcg/openrisc/test_sfne.c
new file mode 100644
index 0000000..064650c
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfne.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0;
+    b = 3;
+    result = 3;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 3\n\t"
+     "l.sfne   %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfne error\n");
+    }
+
+    a = 0;
+    b = 3;
+    result = 3;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfne   %0, %1\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sfne error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sfnei.c b/tests/tcg/openrisc/test_sfnei.c
new file mode 100644
index 0000000..cbc48d4
--- /dev/null
+++ b/tests/tcg/openrisc/test_sfnei.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a;
+    int result;
+
+    a = 0;
+    result = 3;
+
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 3\n\t"
+     "l.sfnei  %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfnei error\n");
+    }
+
+    a = 0;
+    result = 3;
+    __asm
+    ("1:\n\t"
+     "l.addi   %0, %0, 1\n\t"
+     "l.sfnei  %0, 0x3\n\t"
+     "l.bf 1b\n\t"
+     "l.nop\n\t"
+     : "+r"(a)
+    );
+    if (a != result) {
+        printf("sfnei error\n");
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/openrisc/test_sub.c b/tests/tcg/openrisc/test_sub.c
new file mode 100644
index 0000000..f4b0174
--- /dev/null
+++ b/tests/tcg/openrisc/test_sub.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+
+int main(void)
+{
+    int a, b;
+    int result;
+
+    a = 0x100;
+    b = 0x100;
+    result = 0x0;
+
+    __asm
+    ("l.sub %0, %0, %1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sub error\n");
+    }
+
+    a = 0xffff;
+    b = 0x1;
+    result = 0xfffe;
+    __asm
+    ("l.sub %0, %0, %1\n\t"
+     : "+r"(a)
+     : "r"(b)
+    );
+    if (a != result) {
+        printf("sub error\n");
+    }
+
+    return 0;
+}
-- 
1.7.9.5

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

* Re: [Qemu-devel] [PATCH v6 11/16] target-or32: Add a IIS dummy board
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 11/16] target-or32: Add a IIS dummy board Jia Liu
@ 2012-06-21  8:19   ` 陳韋任 (Wei-Ren Chen)
  2012-06-21  9:10     ` Max Filippov
  2012-06-21  9:11     ` Jia Liu
  2012-06-21  9:03   ` Peter Crosthwaite
  1 sibling, 2 replies; 25+ messages in thread
From: 陳韋任 (Wei-Ren Chen) @ 2012-06-21  8:19 UTC (permalink / raw)
  To: Jia Liu; +Cc: qemu-devel

> + *  OpenRISC simulator for use as an ISS.
                                        ^^^
  Shoudld be IIS?

Regards,
chenwj

-- 
Wei-Ren Chen (陳韋任)
Computer Systems Lab, Institute of Information Science,
Academia Sinica, Taiwan (R.O.C.)
Tel:886-2-2788-3799 #1667
Homepage: http://people.cs.nctu.edu.tw/~chenwj

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

* Re: [Qemu-devel] [PATCH v6 11/16] target-or32: Add a IIS dummy board
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 11/16] target-or32: Add a IIS dummy board Jia Liu
  2012-06-21  8:19   ` 陳韋任 (Wei-Ren Chen)
@ 2012-06-21  9:03   ` Peter Crosthwaite
  2012-06-25  2:23     ` Jia Liu
  1 sibling, 1 reply; 25+ messages in thread
From: Peter Crosthwaite @ 2012-06-21  9:03 UTC (permalink / raw)
  To: Jia Liu; +Cc: qemu-devel

On Thu, Jun 21, 2012 at 12:58 PM, Jia Liu <proljc@gmail.com> wrote:
> Add a IIS dummy board.
>
> Signed-off-by: Jia Liu <proljc@gmail.com>
> ---
>  hw/openrisc/Makefile.objs |    2 +-
>  hw/openrisc_sim.c         |  160 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 161 insertions(+), 1 deletion(-)
>  create mode 100644 hw/openrisc_sim.c
>
> diff --git a/hw/openrisc/Makefile.objs b/hw/openrisc/Makefile.objs
> index 1c541a5..38ff8f5 100644
> --- a/hw/openrisc/Makefile.objs
> +++ b/hw/openrisc/Makefile.objs
> @@ -1,3 +1,3 @@
> -obj-y = openrisc_pic.o openrisc_timer.o
> +obj-y = openrisc_pic.o openrisc_sim.o openrisc_timer.o
>
>  obj-y := $(addprefix ../,$(obj-y))
> diff --git a/hw/openrisc_sim.c b/hw/openrisc_sim.c
> new file mode 100644
> index 0000000..892c67f
> --- /dev/null
> +++ b/hw/openrisc_sim.c
> @@ -0,0 +1,160 @@
> +/*
> + *  OpenRISC simulator for use as an ISS.
> + *
> + *  Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
> + *                          Feng Gao <gf91597@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 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/>.
> + */
> +
> +#include "hw.h"
> +#include "openrisc_cpudev.h"
> +#include "boards.h"
> +#include "elf.h"
> +#include "pc.h"
> +#include "loader.h"
> +#include "exec-memory.h"
> +#include "sysemu.h"
> +#include "sysbus.h"
> +#include "qtest.h"
> +
> +#define KERNEL_LOAD_ADDR 0x100
> +
> +static struct _loaderparams {
> +    uint64_t ram_size;
> +    const char *kernel_filename;
> +    const char *kernel_cmdline;
> +    const char *initrd_filename;
> +} loaderparams;
> +
> +static void main_cpu_reset(void *opaque)
> +{
> +    CPUOpenRISCState *env = opaque;
> +    cpu_reset(ENV_GET_CPU(env));
> +}
> +
> +static void openrisc_sim_net_init(MemoryRegion *address_space,
> +                                  target_phys_addr_t base,
> +                                  target_phys_addr_t descriptors,
> +                                  qemu_irq irq, NICInfo *nd)
> +{
> +    DeviceState *dev;
> +    SysBusDevice *s;
> +
> +    dev = qdev_create(NULL, "open_eth");
> +    qdev_set_nic_properties(dev, nd);
> +    qdev_init_nofail(dev);
> +
> +    s = sysbus_from_qdev(dev);
> +    sysbus_connect_irq(s, 0, irq);
> +    memory_region_add_subregion(address_space, base,
> +                                sysbus_mmio_get_region(s, 0));
> +    memory_region_add_subregion(address_space, descriptors,
> +                                sysbus_mmio_get_region(s, 1));
> +}
> +
> +static uint64_t openrisc_load_kernel(void)
> +{
> +    long kernel_size;
> +    uint64_t elf_entry;
> +    target_phys_addr_t entry;
> +
> +    if (loaderparams.kernel_filename && !qtest_enabled()) {
> +        kernel_size = load_elf(loaderparams.kernel_filename, NULL, NULL,
> +                               &elf_entry, NULL, NULL, 1, ELF_MACHINE, 1);
> +        entry = elf_entry;
> +        if (kernel_size < 0) {
> +            kernel_size = load_uimage(loaderparams.kernel_filename,
> +                                      &entry, NULL, NULL);
> +        }
> +        if (kernel_size < 0) {
> +            kernel_size = load_image_targphys(loaderparams.kernel_filename,
> +                                              KERNEL_LOAD_ADDR,
> +                                              ram_size - KERNEL_LOAD_ADDR);
> +            entry = KERNEL_LOAD_ADDR;
> +        }
> +        if (kernel_size < 0) {
> +            fprintf(stderr, "qemu: could not load kernel '%s'\n",
> +                    loaderparams.kernel_filename);
> +            exit(1);
> +        }
> +
> +        if (kernel_size > 0) {
> +            return elf_entry;
> +        }

Hi Jia,

This seems a little weird. What happens here when it successfully
loads a uimage or raw image? It returns the elf_entry (probably == 0)
as the load address?

Regards,
Peter

> +    } else {
> +        entry = 0;
> +    }
> +
> +    return entry;
> +}
> +
> +static void openrisc_sim_init(ram_addr_t ram_size,
> +                              const char *boot_device,
> +                              const char *kernel_filename,
> +                              const char *kernel_cmdline,
> +                              const char *initrd_filename,
> +                              const char *cpu_model)
> +{
> +    CPUOpenRISCState *env;
> +    MemoryRegion *ram = g_new(MemoryRegion, 1);
> +
> +    if (!cpu_model) {
> +        cpu_model = "or1200";
> +    }
> +    env = cpu_init(cpu_model);
> +    if (!env) {
> +        fprintf(stderr, "Unable to find CPU definition!\n");
> +        exit(1);
> +    }
> +
> +    qemu_register_reset(main_cpu_reset, env);
> +    main_cpu_reset(env);
> +
> +    memory_region_init_ram(ram, "openrisc.ram", ram_size);
> +    memory_region_add_subregion(get_system_memory(), 0, ram);
> +
> +    if (kernel_filename) {
> +        loaderparams.ram_size = ram_size;
> +        loaderparams.kernel_filename = kernel_filename;
> +        loaderparams.kernel_cmdline = kernel_cmdline;
> +        env->pc = openrisc_load_kernel();
> +    }
> +
> +    cpu_openrisc_pic_init(env);
> +    cpu_openrisc_clock_init(env);
> +
> +    serial_mm_init(get_system_memory(), 0x90000000, 0,
> +                   env->irq[2], 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);
> +
> +    if (nd_table[0].vlan) {
> +        openrisc_sim_net_init(get_system_memory(), 0x92000000,
> +                              0x92000400, env->irq[4], nd_table);
> +    }
> +}
> +
> +static QEMUMachine openrisc_sim_machine = {
> +    .name = "or32-sim",
> +    .desc = "or32 simulation",
> +    .init = openrisc_sim_init,
> +    .max_cpus = 1,
> +    .is_default = 1,
> +};
> +
> +static void openrisc_sim_machine_init(void)
> +{
> +    qemu_register_machine(&openrisc_sim_machine);
> +}
> +
> +machine_init(openrisc_sim_machine_init);
> --
> 1.7.9.5
>
>

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

* Re: [Qemu-devel] [PATCH v6 11/16] target-or32: Add a IIS dummy board
  2012-06-21  8:19   ` 陳韋任 (Wei-Ren Chen)
@ 2012-06-21  9:10     ` Max Filippov
  2012-06-21  9:11     ` Jia Liu
  1 sibling, 0 replies; 25+ messages in thread
From: Max Filippov @ 2012-06-21  9:10 UTC (permalink / raw)
  To: 陳韋任 (Wei-Ren Chen); +Cc: Jia Liu, qemu-devel

On Thu, Jun 21, 2012 at 12:19 PM, 陳韋任 (Wei-Ren Chen)
<chenwj@iis.sinica.edu.tw> wrote:
>> + *  OpenRISC simulator for use as an ISS.
>                                        ^^^
>  Shoudld be IIS?

I guess it stands for Instruction Set Simulator, so rather the subject
should be changed.

-- 
Thanks.
-- Max

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

* Re: [Qemu-devel] [PATCH v6 11/16] target-or32: Add a IIS dummy board
  2012-06-21  8:19   ` 陳韋任 (Wei-Ren Chen)
  2012-06-21  9:10     ` Max Filippov
@ 2012-06-21  9:11     ` Jia Liu
  1 sibling, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-21  9:11 UTC (permalink / raw)
  To: 陳韋任 (Wei-Ren Chen); +Cc: qemu-devel

Hello Wei-Ren,

On Thu, Jun 21, 2012 at 4:19 PM, 陳韋任 (Wei-Ren Chen)
<chenwj@iis.sinica.edu.tw> wrote:
>> + *  OpenRISC simulator for use as an ISS.
>                                        ^^^
>  Shoudld be IIS?
>

Instruction Set Sim
Instruction Level Sim
What ever, I'll make it more clear :)

> Regards,
> chenwj
>
> --
> Wei-Ren Chen (陳韋任)
> Computer Systems Lab, Institute of Information Science,
> Academia Sinica, Taiwan (R.O.C.)
> Tel:886-2-2788-3799 #1667
> Homepage: http://people.cs.nctu.edu.tw/~chenwj

Regards,
Jia.

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

* Re: [Qemu-devel] [PATCH v6 08/16] target-or32: Add instruction tanslation
  2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 08/16] target-or32: Add instruction tanslation Jia Liu
@ 2012-06-21 10:24   ` Max Filippov
  2012-06-25  2:50     ` Jia Liu
  0 siblings, 1 reply; 25+ messages in thread
From: Max Filippov @ 2012-06-21 10:24 UTC (permalink / raw)
  To: Jia Liu; +Cc: qemu-devel

On Thu, Jun 21, 2012 at 6:58 AM, Jia Liu <proljc@gmail.com> wrote:
> Add OpenRISC instruction tanslation routines.
>
> Signed-off-by: Jia Liu <proljc@gmail.com>

[...]

> +    case 0x0009:
> +        switch (op1) {
> +        case 0x03:   /*l.div*/
> +            LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
> +            {
> +                int lab0 = gen_new_label();
> +                int lab1 = gen_new_label();
> +                int lab2 = gen_new_label();
> +                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
> +                if (rb == 0) {
> +                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
> +                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);
> +                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
> +                    gen_exception(dc, EXCP_RANGE);
> +                    gen_set_label(lab0);
> +                } else {
> +                    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[rb],
> +                                       0x00000000, lab1);
> +                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[ra],
> +                                       0xffffffff, lab2);
> +                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],
> +                                       0x80000000, lab2);
> +                    gen_set_label(lab1);
> +                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
> +                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
> +                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab2);

Causes host division by zero/overflow. I'd suggest to brcond to lab3 set after
the final tcg_gen_div.

> +                    gen_exception(dc, EXCP_RANGE);
> +                    gen_set_label(lab2);
> +                    tcg_gen_div_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
> +                }
> +                tcg_temp_free_i32(sr_ove);
> +            }
> +            break;
> +
> +        default:
> +            gen_illegal_exception(dc);
> +            break;
> +        }
> +        break;
> +
> +    case 0x000a:
> +        switch (op1) {
> +        case 0x03:   /*l.divu*/
> +            LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
> +            {
> +                int lab0 = gen_new_label();
> +                int lab1 = gen_new_label();
> +                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
> +                if (rb == 0) {
> +                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
> +                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
> +                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);
> +                    gen_exception(dc, EXCP_RANGE);
> +                    gen_set_label(lab0);
> +                } else {
> +                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],
> +                                       0x00000000, lab1);
> +                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
> +                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
> +                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab1);

Ditto.

> +                    gen_exception(dc, EXCP_RANGE);
> +                    gen_set_label(lab1);
> +                    tcg_gen_divu_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
> +                }
> +                tcg_temp_free_i32(sr_ove);
> +            }
> +            break;

[...]

> +    case 0x000e:
> +        switch (op1) {
> +        case 0x00:   /*l.cmov*/
> +            LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
> +            {
> +                int lab = gen_new_label();
> +                TCGv res = tcg_temp_new();

Need to be temp_local to survive brcond.

> +                TCGv sr_f = tcg_temp_new();
> +                tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);
> +                tcg_gen_mov_tl(res, cpu_R[rb]);
> +                tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab);
> +                tcg_gen_mov_tl(res, cpu_R[ra]);
> +                gen_set_label(lab);
> +                tcg_gen_mov_tl(cpu_R[rd], res);
> +                tcg_temp_free(sr_f);
> +                tcg_temp_free(res);
> +            }
> +            break;

[...]

-- 
Thanks.
-- Max

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

* Re: [Qemu-devel] [PATCH v6 11/16] target-or32: Add a IIS dummy board
  2012-06-21  9:03   ` Peter Crosthwaite
@ 2012-06-25  2:23     ` Jia Liu
  2012-06-25  2:33       ` Peter Crosthwaite
  0 siblings, 1 reply; 25+ messages in thread
From: Jia Liu @ 2012-06-25  2:23 UTC (permalink / raw)
  To: Peter Crosthwaite; +Cc: qemu-devel

Hi Peter,

On Thu, Jun 21, 2012 at 5:03 PM, Peter Crosthwaite
<peter.crosthwaite@petalogix.com> wrote:
> On Thu, Jun 21, 2012 at 12:58 PM, Jia Liu <proljc@gmail.com> wrote:
>> Add a IIS dummy board.
>>
>> Signed-off-by: Jia Liu <proljc@gmail.com>
>> ---
>>  hw/openrisc/Makefile.objs |    2 +-
>>  hw/openrisc_sim.c         |  160 +++++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 161 insertions(+), 1 deletion(-)
>>  create mode 100644 hw/openrisc_sim.c
>>
>> diff --git a/hw/openrisc/Makefile.objs b/hw/openrisc/Makefile.objs
>> index 1c541a5..38ff8f5 100644
>> --- a/hw/openrisc/Makefile.objs
>> +++ b/hw/openrisc/Makefile.objs
>> @@ -1,3 +1,3 @@
>> -obj-y = openrisc_pic.o openrisc_timer.o
>> +obj-y = openrisc_pic.o openrisc_sim.o openrisc_timer.o
>>
>>  obj-y := $(addprefix ../,$(obj-y))
>> diff --git a/hw/openrisc_sim.c b/hw/openrisc_sim.c
>> new file mode 100644
>> index 0000000..892c67f
>> --- /dev/null
>> +++ b/hw/openrisc_sim.c
>> @@ -0,0 +1,160 @@
>> +/*
>> + *  OpenRISC simulator for use as an ISS.
>> + *
>> + *  Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
>> + *                          Feng Gao <gf91597@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 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/>.
>> + */
>> +
>> +#include "hw.h"
>> +#include "openrisc_cpudev.h"
>> +#include "boards.h"
>> +#include "elf.h"
>> +#include "pc.h"
>> +#include "loader.h"
>> +#include "exec-memory.h"
>> +#include "sysemu.h"
>> +#include "sysbus.h"
>> +#include "qtest.h"
>> +
>> +#define KERNEL_LOAD_ADDR 0x100
>> +
>> +static struct _loaderparams {
>> +    uint64_t ram_size;
>> +    const char *kernel_filename;
>> +    const char *kernel_cmdline;
>> +    const char *initrd_filename;
>> +} loaderparams;
>> +
>> +static void main_cpu_reset(void *opaque)
>> +{
>> +    CPUOpenRISCState *env = opaque;
>> +    cpu_reset(ENV_GET_CPU(env));
>> +}
>> +
>> +static void openrisc_sim_net_init(MemoryRegion *address_space,
>> +                                  target_phys_addr_t base,
>> +                                  target_phys_addr_t descriptors,
>> +                                  qemu_irq irq, NICInfo *nd)
>> +{
>> +    DeviceState *dev;
>> +    SysBusDevice *s;
>> +
>> +    dev = qdev_create(NULL, "open_eth");
>> +    qdev_set_nic_properties(dev, nd);
>> +    qdev_init_nofail(dev);
>> +
>> +    s = sysbus_from_qdev(dev);
>> +    sysbus_connect_irq(s, 0, irq);
>> +    memory_region_add_subregion(address_space, base,
>> +                                sysbus_mmio_get_region(s, 0));
>> +    memory_region_add_subregion(address_space, descriptors,
>> +                                sysbus_mmio_get_region(s, 1));
>> +}
>> +
>> +static uint64_t openrisc_load_kernel(void)
>> +{
>> +    long kernel_size;
>> +    uint64_t elf_entry;
>> +    target_phys_addr_t entry;
>> +
>> +    if (loaderparams.kernel_filename && !qtest_enabled()) {
>> +        kernel_size = load_elf(loaderparams.kernel_filename, NULL, NULL,
>> +                               &elf_entry, NULL, NULL, 1, ELF_MACHINE, 1);
>> +        entry = elf_entry;
>> +        if (kernel_size < 0) {
>> +            kernel_size = load_uimage(loaderparams.kernel_filename,
>> +                                      &entry, NULL, NULL);
>> +        }
>> +        if (kernel_size < 0) {
>> +            kernel_size = load_image_targphys(loaderparams.kernel_filename,
>> +                                              KERNEL_LOAD_ADDR,
>> +                                              ram_size - KERNEL_LOAD_ADDR);
>> +            entry = KERNEL_LOAD_ADDR;
>> +        }
>> +        if (kernel_size < 0) {
>> +            fprintf(stderr, "qemu: could not load kernel '%s'\n",
>> +                    loaderparams.kernel_filename);
>> +            exit(1);
>> +        }
>> +
>> +        if (kernel_size > 0) {
>> +            return elf_entry;
>> +        }
>
> Hi Jia,
>
> This seems a little weird. What happens here when it successfully
> loads a uimage or raw image? It returns the elf_entry (probably == 0)
> as the load address?
>

Thank you for pointing this.
I copy this file from dummy_m68k.c without fully understood, my fault.

Is this code OK?

static uint64_t openrisc_load_kernel(void)
{
    long kernel_size;
    uint64_t elf_entry;
    target_phys_addr_t entry;

    if (loaderparams.kernel_filename && !qtest_enabled()) {
        kernel_size = load_uimage(loaderparams.kernel_filename,
                                  &entry, NULL, NULL);
        if (kernel_size < 0) {
            kernel_size = load_elf(loaderparams.kernel_filename, NULL, NULL,
                                   &elf_entry, NULL, NULL, 1, ELF_MACHINE, 1);
            entry = elf_entry;
        }

        if (kernel_size < 0) {
            fprintf(stderr, "QEMU: couldn't load the kernel '%s'\n",
                    loaderparams.kernel_filename);
            exit(1);
        }
    }

    return entry;
}


> Regards,
> Peter
>
>> +    } else {
>> +        entry = 0;
>> +    }
>> +
>> +    return entry;
>> +}
>> +
>> +static void openrisc_sim_init(ram_addr_t ram_size,
>> +                              const char *boot_device,
>> +                              const char *kernel_filename,
>> +                              const char *kernel_cmdline,
>> +                              const char *initrd_filename,
>> +                              const char *cpu_model)
>> +{
>> +    CPUOpenRISCState *env;
>> +    MemoryRegion *ram = g_new(MemoryRegion, 1);
>> +
>> +    if (!cpu_model) {
>> +        cpu_model = "or1200";
>> +    }
>> +    env = cpu_init(cpu_model);
>> +    if (!env) {
>> +        fprintf(stderr, "Unable to find CPU definition!\n");
>> +        exit(1);
>> +    }
>> +
>> +    qemu_register_reset(main_cpu_reset, env);
>> +    main_cpu_reset(env);
>> +
>> +    memory_region_init_ram(ram, "openrisc.ram", ram_size);
>> +    memory_region_add_subregion(get_system_memory(), 0, ram);
>> +
>> +    if (kernel_filename) {
>> +        loaderparams.ram_size = ram_size;
>> +        loaderparams.kernel_filename = kernel_filename;
>> +        loaderparams.kernel_cmdline = kernel_cmdline;
>> +        env->pc = openrisc_load_kernel();
>> +    }
>> +
>> +    cpu_openrisc_pic_init(env);
>> +    cpu_openrisc_clock_init(env);
>> +
>> +    serial_mm_init(get_system_memory(), 0x90000000, 0,
>> +                   env->irq[2], 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);
>> +
>> +    if (nd_table[0].vlan) {
>> +        openrisc_sim_net_init(get_system_memory(), 0x92000000,
>> +                              0x92000400, env->irq[4], nd_table);
>> +    }
>> +}
>> +
>> +static QEMUMachine openrisc_sim_machine = {
>> +    .name = "or32-sim",
>> +    .desc = "or32 simulation",
>> +    .init = openrisc_sim_init,
>> +    .max_cpus = 1,
>> +    .is_default = 1,
>> +};
>> +
>> +static void openrisc_sim_machine_init(void)
>> +{
>> +    qemu_register_machine(&openrisc_sim_machine);
>> +}
>> +
>> +machine_init(openrisc_sim_machine_init);
>> --
>> 1.7.9.5
>>
>>

Regards,
Jia.

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

* Re: [Qemu-devel] [PATCH v6 11/16] target-or32: Add a IIS dummy board
  2012-06-25  2:23     ` Jia Liu
@ 2012-06-25  2:33       ` Peter Crosthwaite
  0 siblings, 0 replies; 25+ messages in thread
From: Peter Crosthwaite @ 2012-06-25  2:33 UTC (permalink / raw)
  To: Jia Liu; +Cc: qemu-devel

On Mon, Jun 25, 2012 at 12:23 PM, Jia Liu <proljc@gmail.com> wrote:
> Hi Peter,
>
> On Thu, Jun 21, 2012 at 5:03 PM, Peter Crosthwaite
> <peter.crosthwaite@petalogix.com> wrote:
>> On Thu, Jun 21, 2012 at 12:58 PM, Jia Liu <proljc@gmail.com> wrote:
>>> Add a IIS dummy board.
>>>
>>> Signed-off-by: Jia Liu <proljc@gmail.com>
>>> ---
>>>  hw/openrisc/Makefile.objs |    2 +-
>>>  hw/openrisc_sim.c         |  160 +++++++++++++++++++++++++++++++++++++++++++++
>>>  2 files changed, 161 insertions(+), 1 deletion(-)
>>>  create mode 100644 hw/openrisc_sim.c
>>>
>>> diff --git a/hw/openrisc/Makefile.objs b/hw/openrisc/Makefile.objs
>>> index 1c541a5..38ff8f5 100644
>>> --- a/hw/openrisc/Makefile.objs
>>> +++ b/hw/openrisc/Makefile.objs
>>> @@ -1,3 +1,3 @@
>>> -obj-y = openrisc_pic.o openrisc_timer.o
>>> +obj-y = openrisc_pic.o openrisc_sim.o openrisc_timer.o
>>>
>>>  obj-y := $(addprefix ../,$(obj-y))
>>> diff --git a/hw/openrisc_sim.c b/hw/openrisc_sim.c
>>> new file mode 100644
>>> index 0000000..892c67f
>>> --- /dev/null
>>> +++ b/hw/openrisc_sim.c
>>> @@ -0,0 +1,160 @@
>>> +/*
>>> + *  OpenRISC simulator for use as an ISS.
>>> + *
>>> + *  Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
>>> + *                          Feng Gao <gf91597@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 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/>.
>>> + */
>>> +
>>> +#include "hw.h"
>>> +#include "openrisc_cpudev.h"
>>> +#include "boards.h"
>>> +#include "elf.h"
>>> +#include "pc.h"
>>> +#include "loader.h"
>>> +#include "exec-memory.h"
>>> +#include "sysemu.h"
>>> +#include "sysbus.h"
>>> +#include "qtest.h"
>>> +
>>> +#define KERNEL_LOAD_ADDR 0x100
>>> +
>>> +static struct _loaderparams {
>>> +    uint64_t ram_size;
>>> +    const char *kernel_filename;
>>> +    const char *kernel_cmdline;
>>> +    const char *initrd_filename;
>>> +} loaderparams;
>>> +
>>> +static void main_cpu_reset(void *opaque)
>>> +{
>>> +    CPUOpenRISCState *env = opaque;
>>> +    cpu_reset(ENV_GET_CPU(env));
>>> +}
>>> +
>>> +static void openrisc_sim_net_init(MemoryRegion *address_space,
>>> +                                  target_phys_addr_t base,
>>> +                                  target_phys_addr_t descriptors,
>>> +                                  qemu_irq irq, NICInfo *nd)
>>> +{
>>> +    DeviceState *dev;
>>> +    SysBusDevice *s;
>>> +
>>> +    dev = qdev_create(NULL, "open_eth");
>>> +    qdev_set_nic_properties(dev, nd);
>>> +    qdev_init_nofail(dev);
>>> +
>>> +    s = sysbus_from_qdev(dev);
>>> +    sysbus_connect_irq(s, 0, irq);
>>> +    memory_region_add_subregion(address_space, base,
>>> +                                sysbus_mmio_get_region(s, 0));
>>> +    memory_region_add_subregion(address_space, descriptors,
>>> +                                sysbus_mmio_get_region(s, 1));
>>> +}
>>> +
>>> +static uint64_t openrisc_load_kernel(void)
>>> +{
>>> +    long kernel_size;
>>> +    uint64_t elf_entry;
>>> +    target_phys_addr_t entry;
>>> +
>>> +    if (loaderparams.kernel_filename && !qtest_enabled()) {
>>> +        kernel_size = load_elf(loaderparams.kernel_filename, NULL, NULL,
>>> +                               &elf_entry, NULL, NULL, 1, ELF_MACHINE, 1);
>>> +        entry = elf_entry;
>>> +        if (kernel_size < 0) {
>>> +            kernel_size = load_uimage(loaderparams.kernel_filename,
>>> +                                      &entry, NULL, NULL);
>>> +        }
>>> +        if (kernel_size < 0) {
>>> +            kernel_size = load_image_targphys(loaderparams.kernel_filename,
>>> +                                              KERNEL_LOAD_ADDR,
>>> +                                              ram_size - KERNEL_LOAD_ADDR);
>>> +            entry = KERNEL_LOAD_ADDR;
>>> +        }
>>> +        if (kernel_size < 0) {
>>> +            fprintf(stderr, "qemu: could not load kernel '%s'\n",
>>> +                    loaderparams.kernel_filename);
>>> +            exit(1);
>>> +        }
>>> +
>>> +        if (kernel_size > 0) {
>>> +            return elf_entry;
>>> +        }
>>
>> Hi Jia,
>>
>> This seems a little weird. What happens here when it successfully
>> loads a uimage or raw image? It returns the elf_entry (probably == 0)
>> as the load address?
>>
>
> Thank you for pointing this.
> I copy this file from dummy_m68k.c without fully understood, my fault.
>
> Is this code OK?
>

Yep, Looks better.

Regards,
Peter

> static uint64_t openrisc_load_kernel(void)
> {
>    long kernel_size;
>    uint64_t elf_entry;
>    target_phys_addr_t entry;
>
>    if (loaderparams.kernel_filename && !qtest_enabled()) {
>        kernel_size = load_uimage(loaderparams.kernel_filename,
>                                  &entry, NULL, NULL);
>        if (kernel_size < 0) {
>            kernel_size = load_elf(loaderparams.kernel_filename, NULL, NULL,
>                                   &elf_entry, NULL, NULL, 1, ELF_MACHINE, 1);
>            entry = elf_entry;
>        }
>
>        if (kernel_size < 0) {
>            fprintf(stderr, "QEMU: couldn't load the kernel '%s'\n",
>                    loaderparams.kernel_filename);
>            exit(1);
>        }
>    }
>
>    return entry;
> }
>
>
>> Regards,
>> Peter
>>
>>> +    } else {
>>> +        entry = 0;
>>> +    }
>>> +
>>> +    return entry;
>>> +}
>>> +
>>> +static void openrisc_sim_init(ram_addr_t ram_size,
>>> +                              const char *boot_device,
>>> +                              const char *kernel_filename,
>>> +                              const char *kernel_cmdline,
>>> +                              const char *initrd_filename,
>>> +                              const char *cpu_model)
>>> +{
>>> +    CPUOpenRISCState *env;
>>> +    MemoryRegion *ram = g_new(MemoryRegion, 1);
>>> +
>>> +    if (!cpu_model) {
>>> +        cpu_model = "or1200";
>>> +    }
>>> +    env = cpu_init(cpu_model);
>>> +    if (!env) {
>>> +        fprintf(stderr, "Unable to find CPU definition!\n");
>>> +        exit(1);
>>> +    }
>>> +
>>> +    qemu_register_reset(main_cpu_reset, env);
>>> +    main_cpu_reset(env);
>>> +
>>> +    memory_region_init_ram(ram, "openrisc.ram", ram_size);
>>> +    memory_region_add_subregion(get_system_memory(), 0, ram);
>>> +
>>> +    if (kernel_filename) {
>>> +        loaderparams.ram_size = ram_size;
>>> +        loaderparams.kernel_filename = kernel_filename;
>>> +        loaderparams.kernel_cmdline = kernel_cmdline;
>>> +        env->pc = openrisc_load_kernel();
>>> +    }
>>> +
>>> +    cpu_openrisc_pic_init(env);
>>> +    cpu_openrisc_clock_init(env);
>>> +
>>> +    serial_mm_init(get_system_memory(), 0x90000000, 0,
>>> +                   env->irq[2], 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);
>>> +
>>> +    if (nd_table[0].vlan) {
>>> +        openrisc_sim_net_init(get_system_memory(), 0x92000000,
>>> +                              0x92000400, env->irq[4], nd_table);
>>> +    }
>>> +}
>>> +
>>> +static QEMUMachine openrisc_sim_machine = {
>>> +    .name = "or32-sim",
>>> +    .desc = "or32 simulation",
>>> +    .init = openrisc_sim_init,
>>> +    .max_cpus = 1,
>>> +    .is_default = 1,
>>> +};
>>> +
>>> +static void openrisc_sim_machine_init(void)
>>> +{
>>> +    qemu_register_machine(&openrisc_sim_machine);
>>> +}
>>> +
>>> +machine_init(openrisc_sim_machine_init);
>>> --
>>> 1.7.9.5
>>>
>>>
>
> Regards,
> Jia.

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

* Re: [Qemu-devel] [PATCH v6 08/16] target-or32: Add instruction tanslation
  2012-06-21 10:24   ` Max Filippov
@ 2012-06-25  2:50     ` Jia Liu
  0 siblings, 0 replies; 25+ messages in thread
From: Jia Liu @ 2012-06-25  2:50 UTC (permalink / raw)
  To: Max Filippov; +Cc: qemu-devel

Hi Max,

On Thu, Jun 21, 2012 at 6:24 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
> On Thu, Jun 21, 2012 at 6:58 AM, Jia Liu <proljc@gmail.com> wrote:
>> Add OpenRISC instruction tanslation routines.
>>
>> Signed-off-by: Jia Liu <proljc@gmail.com>
>
> [...]
>
>> +    case 0x0009:
>> +        switch (op1) {
>> +        case 0x03:   /*l.div*/
>> +            LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
>> +            {
>> +                int lab0 = gen_new_label();
>> +                int lab1 = gen_new_label();
>> +                int lab2 = gen_new_label();
>> +                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
>> +                if (rb == 0) {
>> +                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
>> +                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);
>> +                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
>> +                    gen_exception(dc, EXCP_RANGE);
>> +                    gen_set_label(lab0);
>> +                } else {
>> +                    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[rb],
>> +                                       0x00000000, lab1);
>> +                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[ra],
>> +                                       0xffffffff, lab2);
>> +                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],
>> +                                       0x80000000, lab2);
>> +                    gen_set_label(lab1);
>> +                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
>> +                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
>> +                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab2);
>
> Causes host division by zero/overflow. I'd suggest to brcond to lab3 set after
> the final tcg_gen_div.

Causes host division by zero/overflow? Can I handle the host code? I'm
confused about this.
May I get more comment about this? Sorry I didn't understand it.

>
>> +                    gen_exception(dc, EXCP_RANGE);
>> +                    gen_set_label(lab2);
>> +                    tcg_gen_div_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
>> +                }
>> +                tcg_temp_free_i32(sr_ove);
>> +            }
>> +            break;
>> +
>> +        default:
>> +            gen_illegal_exception(dc);
>> +            break;
>> +        }
>> +        break;
>> +
>> +    case 0x000a:
>> +        switch (op1) {
>> +        case 0x03:   /*l.divu*/
>> +            LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
>> +            {
>> +                int lab0 = gen_new_label();
>> +                int lab1 = gen_new_label();
>> +                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
>> +                if (rb == 0) {
>> +                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
>> +                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
>> +                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);
>> +                    gen_exception(dc, EXCP_RANGE);
>> +                    gen_set_label(lab0);
>> +                } else {
>> +                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],
>> +                                       0x00000000, lab1);
>> +                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
>> +                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
>> +                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab1);
>
> Ditto.
>
>> +                    gen_exception(dc, EXCP_RANGE);
>> +                    gen_set_label(lab1);
>> +                    tcg_gen_divu_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
>> +                }
>> +                tcg_temp_free_i32(sr_ove);
>> +            }
>> +            break;
>
> [...]
>
>> +    case 0x000e:
>> +        switch (op1) {
>> +        case 0x00:   /*l.cmov*/
>> +            LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
>> +            {
>> +                int lab = gen_new_label();
>> +                TCGv res = tcg_temp_new();
>
> Need to be temp_local to survive brcond.
>

Thank you, fixed.

>> +                TCGv sr_f = tcg_temp_new();
>> +                tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);
>> +                tcg_gen_mov_tl(res, cpu_R[rb]);
>> +                tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab);
>> +                tcg_gen_mov_tl(res, cpu_R[ra]);
>> +                gen_set_label(lab);
>> +                tcg_gen_mov_tl(cpu_R[rd], res);
>> +                tcg_temp_free(sr_f);
>> +                tcg_temp_free(res);
>> +            }
>> +            break;
>
> [...]
>
> --
> Thanks.
> -- Max

Regards,
Jia.

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

end of thread, other threads:[~2012-06-25  2:50 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-21  2:57 [Qemu-devel] [PATCH v6 00/16] QEMU OpenRISC support Jia Liu
2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 01/16] target-or32: Add target stubs and cpu support Jia Liu
2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 02/16] target-or32: Add target machine Jia Liu
2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 03/16] target-or32: Add MMU support Jia Liu
2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 04/16] target-or32: Add interrupt support Jia Liu
2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 05/16] target-or32: Add exception support Jia Liu
2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 06/16] target-or32: Add int instruction helpers Jia Liu
2012-06-21  2:57 ` [Qemu-devel] [PATCH v6 07/16] target-or32: Add float " Jia Liu
2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 08/16] target-or32: Add instruction tanslation Jia Liu
2012-06-21 10:24   ` Max Filippov
2012-06-25  2:50     ` Jia Liu
2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 09/16] target-or32: Add PIC support Jia Liu
2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 10/16] target-or32: Add timer support Jia Liu
2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 11/16] target-or32: Add a IIS dummy board Jia Liu
2012-06-21  8:19   ` 陳韋任 (Wei-Ren Chen)
2012-06-21  9:10     ` Max Filippov
2012-06-21  9:11     ` Jia Liu
2012-06-21  9:03   ` Peter Crosthwaite
2012-06-25  2:23     ` Jia Liu
2012-06-25  2:33       ` Peter Crosthwaite
2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 12/16] target-or32: Add system instructions Jia Liu
2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 13/16] target-or32: Add gdb stub Jia Liu
2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 14/16] target-or32: Add linux syscall, signal and termbits Jia Liu
2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 15/16] target-or32: Add linux user support Jia Liu
2012-06-21  2:58 ` [Qemu-devel] [PATCH v6 16/16] target-or32: Add testcases Jia Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).