* [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).