diff --git a/CMakeLists.txt b/CMakeLists.txt
index b92435a804..3d050503c6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,7 +63,7 @@ option(BUILD_SHARED_LIBS "Build shared instead of static library" ${PROJECT_IS_T
 option(UNICORN_FUZZ "Enable fuzzing" OFF)
 option(UNICORN_BUILD_TESTS "Build unicorn tests" ${PROJECT_IS_TOP_LEVEL})
 option(UNICORN_INSTALL "Enable unicorn installation" ${PROJECT_IS_TOP_LEVEL})
-set(UNICORN_ARCH "x86;arm;aarch64;riscv;mips;sparc;m68k;ppc;s390x;tricore" CACHE STRING "Enabled unicorn architectures")
+set(UNICORN_ARCH "x86;arm;aarch64;riscv;mips;sparc;m68k;ppc;rh850;s390x;tricore" CACHE STRING "Enabled unicorn architectures")
 option(UNICORN_TRACER "Trace unicorn execution" OFF)
 
 foreach(ARCH_LOOP ${UNICORN_ARCH})
@@ -268,6 +268,9 @@ else()
     if(UNICORN_HAS_PPC)
         set(EXTRA_CFLAGS "${EXTRA_CFLAGS}-DUNICORN_HAS_PPC ")
     endif()
+    if(UNICORN_HAS_RH850)
+        set(EXTRA_CFLAGS "${EXTRA_CFLAGS}-DUNICORN_HAS_RH850 ")
+    endif()
     if(UNICORN_HAS_RISCV)
         set(EXTRA_CFLAGS "${EXTRA_CFLAGS}-DUNICORN_HAS_RISCV ")
     endif()
@@ -315,6 +318,9 @@ else()
     if(UNICORN_HAS_PPC)
         set(TARGET_LIST "${TARGET_LIST}ppc-softmmu, ppc64-softmmu, ")
     endif()
+    if(UNICORN_HAS_RH850)
+        set(TARGET_LIST "${TARGET_LIST}rh850-softmmu, ")
+    endif()
     if(UNICORN_HAS_RISCV)
         set(TARGET_LIST "${TARGET_LIST}riscv32-softmmu, riscv64-softmmu, ")
     endif()
@@ -399,6 +405,12 @@ else()
             OUTPUT_FILE ${CMAKE_BINARY_DIR}/ppc64-softmmu/config-target.h
         )
     endif()
+    if(UNICORN_HAS_RH850)
+        execute_process(COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/qemu/scripts/create_config
+            INPUT_FILE ${CMAKE_BINARY_DIR}/rh850-softmmu/config-target.mak
+            OUTPUT_FILE ${CMAKE_BINARY_DIR}/rh850-softmmu/config-target.h
+        )
+    endif()
     if(UNICORN_HAS_RISCV)
         execute_process(COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/qemu/scripts/create_config
             INPUT_FILE ${CMAKE_BINARY_DIR}/riscv32-softmmu/config-target.mak
@@ -1119,6 +1131,36 @@ endif()
 endif()
 
 
+if (UNICORN_HAS_RH850)
+add_library(rh850-softmmu STATIC
+    ${UNICORN_ARCH_COMMON}
+
+    qemu/target/rh850/cpu.c
+    qemu/target/rh850/fpu_helper.c
+    qemu/target/rh850/helper.c
+    qemu/target/rh850/op_helper.c
+    qemu/target/rh850/translate.c
+    qemu/target/rh850/fpu_translate.c
+    qemu/target/rh850/unicorn.c
+)
+
+if(MSVC)
+    target_compile_options(rh850-softmmu PRIVATE
+        -DNEED_CPU_H
+        /FIrh850.h
+        /I${CMAKE_CURRENT_SOURCE_DIR}/msvc/rh850-softmmu
+        /I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target/rh850
+    )
+else()
+    target_compile_options(rh850-softmmu PRIVATE
+        -DNEED_CPU_H
+        -include rh850.h
+        -I${CMAKE_BINARY_DIR}/rh850-softmmu
+        -I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target/rh850
+    )
+endif()
+endif()
+
 set(UNICORN_SRCS
     uc.c
 
@@ -1266,6 +1308,13 @@ if(UNICORN_HAS_PPC)
     target_link_libraries(ppc64-softmmu PRIVATE unicorn-common)
     set(UNICORN_TEST_FILE ${UNICORN_TEST_FILE} test_ppc)
 endif()
+if(UNICORN_HAS_RH850)
+    set(UNICORN_COMPILE_OPTIONS ${UNICORN_COMPILE_OPTIONS} -DUNICORN_HAS_RH850)
+    set(UNICORN_LINK_LIBRARIES ${UNICORN_LINK_LIBRARIES} rh850-softmmu rh850-softmmu)
+    set(UNICORN_SAMPLE_FILE ${UNICORN_SAMPLE_FILE} sample_rh850)
+    target_link_libraries(rh850-softmmu PRIVATE unicorn-common)
+    set(UNICORN_TEST_FILE ${UNICORN_TEST_FILE} test_rh850)
+endif()
 if(UNICORN_HAS_RISCV)
     set(UNICORN_COMPILE_OPTIONS ${UNICORN_COMPILE_OPTIONS} -DUNICORN_HAS_RISCV)
     set(UNICORN_LINK_LIBRARIES ${UNICORN_LINK_LIBRARIES} riscv32-softmmu riscv64-softmmu)
diff --git a/Cargo.toml b/Cargo.toml
index 64ab69b2c3..942ce1f304 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -42,7 +42,7 @@ pkg-config = { version = "0.3" }
 [features]
 default = ["arch_all"]
 dynamic_linkage = []
-arch_all = ["arch_x86", "arch_arm", "arch_aarch64", "arch_riscv", "arch_mips", "arch_sparc", "arch_m68k", "arch_ppc", "arch_s390x", "arch_tricore"]
+arch_all = ["arch_x86", "arch_arm", "arch_aarch64", "arch_riscv", "arch_mips", "arch_sparc", "arch_m68k", "arch_ppc", "arch_s390x", "arch_tricore", "arch_rh850"]
 arch_x86 = []
 arch_arm = []
 arch_aarch64 = []
@@ -53,3 +53,4 @@ arch_m68k = []
 arch_ppc = []
 arch_s390x = []
 arch_tricore = []
+arch_rh850 = []
diff --git a/bindings/const_generator.py b/bindings/const_generator.py
index 982b48f4cb..259254a9bd 100644
--- a/bindings/const_generator.py
+++ b/bindings/const_generator.py
@@ -6,7 +6,7 @@
 
 INCL_DIR = os.path.join('..', 'include', 'unicorn')
 
-include = [ 'arm.h', 'arm64.h', 'mips.h', 'x86.h', 'sparc.h', 'm68k.h', 'ppc.h', 'riscv.h', 's390x.h', 'tricore.h', 'unicorn.h' ]
+include = [ 'arm.h', 'arm64.h', 'mips.h', 'x86.h', 'sparc.h', 'm68k.h', 'ppc.h', 'rh850.h', 'riscv.h', 's390x.h', 'tricore.h', 'unicorn.h' ]
 
 template = {
     'python': {
@@ -22,6 +22,7 @@
             'sparc.h': 'sparc',
             'm68k.h': 'm68k',
             'ppc.h': 'ppc',
+            'rh850.h': 'rh850',
             'riscv.h': 'riscv',
             's390x.h' : 's390x',
             'tricore.h' : 'tricore',
@@ -43,6 +44,7 @@
             'm68k.h': 'm68k',
             'ppc.h': 'ppc',
             'riscv.h': 'riscv',
+            'rh850.h': 'rh850',
             's390x.h' : 's390x',
             'tricore.h' : 'tricore',
             'unicorn.h': 'unicorn',
@@ -62,6 +64,7 @@
             'sparc.h': 'sparc',
             'm68k.h': 'm68k',
             'ppc.h': 'ppc',
+            'rh850.h': 'rh850',
             'riscv.h': 'riscv',
             's390x.h' : 's390x',
             'tricore.h' : 'tricore',
@@ -82,6 +85,7 @@
             'sparc.h': 'Sparc',
             'm68k.h': 'M68k',
             'ppc.h': 'Ppc',
+            'rh850.h': 'Rh850',
             'riscv.h': 'Riscv',
             's390x.h' : 'S390x',
             'tricore.h' : 'TriCore',
@@ -102,6 +106,7 @@
             'sparc.h': 'Sparc',
             'm68k.h': 'M68k',
             'ppc.h': 'Ppc',
+            'rh850.h': 'Rh850',
             'riscv.h': 'Riscv',
             's390x.h' : 'S390x',
             'tricore.h' : 'TriCore',
@@ -122,6 +127,7 @@
             'sparc.h': 'Sparc',
             'm68k.h': 'M68k',
             'ppc.h': 'Ppc',
+            'rh850.h': 'Rh850',
             'riscv.h': 'Riscv',
             's390x.h' : 'S390x',
             'tricore.h' : 'TriCore',
@@ -143,6 +149,7 @@
             'm68k.h': 'm68k',
             'ppc.h': 'ppc',
             'riscv.h': 'riscv',
+            'rh850.h': 'rh850',
             's390x.h' : 's390x',
             'tricore.h' : 'tricore',
             'unicorn.h': 'unicorn',
diff --git a/bindings/dotnet/UnicornEngine/Const/Common.fs b/bindings/dotnet/UnicornEngine/Const/Common.fs
index f44d114903..02c813d177 100644
--- a/bindings/dotnet/UnicornEngine/Const/Common.fs
+++ b/bindings/dotnet/UnicornEngine/Const/Common.fs
@@ -28,7 +28,8 @@ module Common =
     let UC_ARCH_RISCV = 8
     let UC_ARCH_S390X = 9
     let UC_ARCH_TRICORE = 10
-    let UC_ARCH_MAX = 11
+    let UC_ARCH_RH850 = 11
+    let UC_ARCH_MAX = 12
 
     let UC_MODE_LITTLE_ENDIAN = 0
     let UC_MODE_BIG_ENDIAN = 1073741824
@@ -55,6 +56,7 @@ module Common =
     let UC_MODE_SPARC32 = 4
     let UC_MODE_SPARC64 = 8
     let UC_MODE_V9 = 16
+    let UC_MODE_RH850 = 4
     let UC_MODE_RISCV32 = 4
     let UC_MODE_RISCV64 = 8
 
diff --git a/bindings/dotnet/UnicornEngine/Const/Rh850.fs b/bindings/dotnet/UnicornEngine/Const/Rh850.fs
new file mode 100644
index 0000000000..073f10416f
--- /dev/null
+++ b/bindings/dotnet/UnicornEngine/Const/Rh850.fs
@@ -0,0 +1,99 @@
+// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
+
+namespace UnicornManaged.Const
+
+open System
+
+[<AutoOpen>]
+module Rh850 =
+    let UC_RH850_SYSREG_SELID0 = 32
+    let UC_RH850_SYSREG_SELID1 = 64
+    let UC_RH850_SYSREG_SELID2 = 96
+    let UC_RH850_SYSREG_SELID3 = 128
+    let UC_RH850_SYSREG_SELID4 = 160
+    let UC_RH850_SYSREG_SELID5 = 192
+    let UC_RH850_SYSREG_SELID6 = 224
+    let UC_RH850_SYSREG_SELID7 = 256
+
+    // RH850 global purpose registers
+
+    let UC_RH850_REG_R0 = 0
+    let UC_RH850_REG_R1 = 1
+    let UC_RH850_REG_R2 = 2
+    let UC_RH850_REG_R3 = 3
+    let UC_RH850_REG_R4 = 4
+    let UC_RH850_REG_R5 = 5
+    let UC_RH850_REG_R6 = 6
+    let UC_RH850_REG_R7 = 7
+    let UC_RH850_REG_R8 = 8
+    let UC_RH850_REG_R9 = 9
+    let UC_RH850_REG_R10 = 10
+    let UC_RH850_REG_R11 = 11
+    let UC_RH850_REG_R12 = 12
+    let UC_RH850_REG_R13 = 13
+    let UC_RH850_REG_R14 = 14
+    let UC_RH850_REG_R15 = 15
+    let UC_RH850_REG_R16 = 16
+    let UC_RH850_REG_R17 = 17
+    let UC_RH850_REG_R18 = 18
+    let UC_RH850_REG_R19 = 19
+    let UC_RH850_REG_R20 = 20
+    let UC_RH850_REG_R21 = 21
+    let UC_RH850_REG_R22 = 22
+    let UC_RH850_REG_R23 = 23
+    let UC_RH850_REG_R24 = 24
+    let UC_RH850_REG_R25 = 25
+    let UC_RH850_REG_R26 = 26
+    let UC_RH850_REG_R27 = 27
+    let UC_RH850_REG_R28 = 28
+    let UC_RH850_REG_R29 = 29
+    let UC_RH850_REG_R30 = 30
+    let UC_RH850_REG_R31 = 31
+
+    // RH850 system registers, selection ID 0
+    let UC_RH850_REG_EIPC = 32
+    let UC_RH850_REG_EIPSW = 33
+    let UC_RH850_REG_FEPC = 34
+    let UC_RH850_REG_FEPSW = 35
+    let UC_RH850_REG_ECR = 36
+    let UC_RH850_REG_PSW = 37
+    let UC_RH850_REG_FPSR = 38
+    let UC_RH850_REG_FPEPC = 39
+    let UC_RH850_REG_FPST = 40
+    let UC_RH850_REG_FPCC = 41
+    let UC_RH850_REG_FPCFG = 42
+    let UC_RH850_REG_FPEC = 43
+    let UC_RH850_REG_EIIC = 45
+    let UC_RH850_REG_FEIC = 46
+    let UC_RH850_REG_CTPC = 48
+    let UC_RH850_REG_CTPSW = 49
+    let UC_RH850_REG_CTBP = 52
+    let UC_RH850_REG_EIWR = 60
+    let UC_RH850_REG_FEWR = 61
+    let UC_RH850_REG_BSEL = 63
+
+    // RH850 system regusters, selection ID 1
+    let UC_RH850_REG_MCFG0 = 64
+    let UC_RH850_REG_RBASE = 65
+    let UC_RH850_REG_EBASE = 66
+    let UC_RH850_REG_INTBP = 67
+    let UC_RH850_REG_MCTL = 68
+    let UC_RH850_REG_PID = 69
+    let UC_RH850_REG_SCCFG = 75
+    let UC_RH850_REG_SCBP = 76
+
+    // RH850 system registers, selection ID 2
+    let UC_RH850_REG_HTCFG0 = 96
+    let UC_RH850_REG_MEA = 102
+    let UC_RH850_REG_ASID = 103
+    let UC_RH850_REG_MEI = 104
+    let UC_RH850_REG_PC = 288
+    let UC_RH850_REG_ENDING = 289
+
+    // RH8509 Registers aliases.
+
+    let UC_RH850_REG_ZERO = 0
+    let UC_RH850_REG_SP = 3
+    let UC_RH850_REG_EP = 30
+    let UC_RH850_REG_LP = 31
+
diff --git a/bindings/go/unicorn/rh850_const.go b/bindings/go/unicorn/rh850_const.go
new file mode 100644
index 0000000000..72ad301628
--- /dev/null
+++ b/bindings/go/unicorn/rh850_const.go
@@ -0,0 +1,94 @@
+package unicorn
+// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [rh850_const.go]
+const (
+	RH850_SYSREG_SELID0 = 32
+	RH850_SYSREG_SELID1 = 64
+	RH850_SYSREG_SELID2 = 96
+	RH850_SYSREG_SELID3 = 128
+	RH850_SYSREG_SELID4 = 160
+	RH850_SYSREG_SELID5 = 192
+	RH850_SYSREG_SELID6 = 224
+	RH850_SYSREG_SELID7 = 256
+
+// RH850 global purpose registers
+
+	RH850_REG_R0 = 0
+	RH850_REG_R1 = 1
+	RH850_REG_R2 = 2
+	RH850_REG_R3 = 3
+	RH850_REG_R4 = 4
+	RH850_REG_R5 = 5
+	RH850_REG_R6 = 6
+	RH850_REG_R7 = 7
+	RH850_REG_R8 = 8
+	RH850_REG_R9 = 9
+	RH850_REG_R10 = 10
+	RH850_REG_R11 = 11
+	RH850_REG_R12 = 12
+	RH850_REG_R13 = 13
+	RH850_REG_R14 = 14
+	RH850_REG_R15 = 15
+	RH850_REG_R16 = 16
+	RH850_REG_R17 = 17
+	RH850_REG_R18 = 18
+	RH850_REG_R19 = 19
+	RH850_REG_R20 = 20
+	RH850_REG_R21 = 21
+	RH850_REG_R22 = 22
+	RH850_REG_R23 = 23
+	RH850_REG_R24 = 24
+	RH850_REG_R25 = 25
+	RH850_REG_R26 = 26
+	RH850_REG_R27 = 27
+	RH850_REG_R28 = 28
+	RH850_REG_R29 = 29
+	RH850_REG_R30 = 30
+	RH850_REG_R31 = 31
+
+// RH850 system registers, selection ID 0
+	RH850_REG_EIPC = 32
+	RH850_REG_EIPSW = 33
+	RH850_REG_FEPC = 34
+	RH850_REG_FEPSW = 35
+	RH850_REG_ECR = 36
+	RH850_REG_PSW = 37
+	RH850_REG_FPSR = 38
+	RH850_REG_FPEPC = 39
+	RH850_REG_FPST = 40
+	RH850_REG_FPCC = 41
+	RH850_REG_FPCFG = 42
+	RH850_REG_FPEC = 43
+	RH850_REG_EIIC = 45
+	RH850_REG_FEIC = 46
+	RH850_REG_CTPC = 48
+	RH850_REG_CTPSW = 49
+	RH850_REG_CTBP = 52
+	RH850_REG_EIWR = 60
+	RH850_REG_FEWR = 61
+	RH850_REG_BSEL = 63
+
+// RH850 system regusters, selection ID 1
+	RH850_REG_MCFG0 = 64
+	RH850_REG_RBASE = 65
+	RH850_REG_EBASE = 66
+	RH850_REG_INTBP = 67
+	RH850_REG_MCTL = 68
+	RH850_REG_PID = 69
+	RH850_REG_SCCFG = 75
+	RH850_REG_SCBP = 76
+
+// RH850 system registers, selection ID 2
+	RH850_REG_HTCFG0 = 96
+	RH850_REG_MEA = 102
+	RH850_REG_ASID = 103
+	RH850_REG_MEI = 104
+	RH850_REG_PC = 288
+	RH850_REG_ENDING = 289
+
+// RH8509 Registers aliases.
+
+	RH850_REG_ZERO = 0
+	RH850_REG_SP = 3
+	RH850_REG_EP = 30
+	RH850_REG_LP = 31
+)
\ No newline at end of file
diff --git a/bindings/go/unicorn/unicorn_const.go b/bindings/go/unicorn/unicorn_const.go
index f82cf91667..7a036992ff 100644
--- a/bindings/go/unicorn/unicorn_const.go
+++ b/bindings/go/unicorn/unicorn_const.go
@@ -23,7 +23,8 @@ const (
 	ARCH_RISCV = 8
 	ARCH_S390X = 9
 	ARCH_TRICORE = 10
-	ARCH_MAX = 11
+	ARCH_RH850 = 11
+	ARCH_MAX = 12
 
 	MODE_LITTLE_ENDIAN = 0
 	MODE_BIG_ENDIAN = 1073741824
@@ -50,6 +51,7 @@ const (
 	MODE_SPARC32 = 4
 	MODE_SPARC64 = 8
 	MODE_V9 = 16
+	MODE_RH850 = 4
 	MODE_RISCV32 = 4
 	MODE_RISCV64 = 8
 
diff --git a/bindings/java/src/main/java/unicorn/Rh850Const.java b/bindings/java/src/main/java/unicorn/Rh850Const.java
new file mode 100644
index 0000000000..098eea41b5
--- /dev/null
+++ b/bindings/java/src/main/java/unicorn/Rh850Const.java
@@ -0,0 +1,97 @@
+// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
+
+package unicorn;
+
+public interface Rh850Const {
+   public static final int UC_RH850_SYSREG_SELID0 = 32;
+   public static final int UC_RH850_SYSREG_SELID1 = 64;
+   public static final int UC_RH850_SYSREG_SELID2 = 96;
+   public static final int UC_RH850_SYSREG_SELID3 = 128;
+   public static final int UC_RH850_SYSREG_SELID4 = 160;
+   public static final int UC_RH850_SYSREG_SELID5 = 192;
+   public static final int UC_RH850_SYSREG_SELID6 = 224;
+   public static final int UC_RH850_SYSREG_SELID7 = 256;
+
+// RH850 global purpose registers
+
+   public static final int UC_RH850_REG_R0 = 0;
+   public static final int UC_RH850_REG_R1 = 1;
+   public static final int UC_RH850_REG_R2 = 2;
+   public static final int UC_RH850_REG_R3 = 3;
+   public static final int UC_RH850_REG_R4 = 4;
+   public static final int UC_RH850_REG_R5 = 5;
+   public static final int UC_RH850_REG_R6 = 6;
+   public static final int UC_RH850_REG_R7 = 7;
+   public static final int UC_RH850_REG_R8 = 8;
+   public static final int UC_RH850_REG_R9 = 9;
+   public static final int UC_RH850_REG_R10 = 10;
+   public static final int UC_RH850_REG_R11 = 11;
+   public static final int UC_RH850_REG_R12 = 12;
+   public static final int UC_RH850_REG_R13 = 13;
+   public static final int UC_RH850_REG_R14 = 14;
+   public static final int UC_RH850_REG_R15 = 15;
+   public static final int UC_RH850_REG_R16 = 16;
+   public static final int UC_RH850_REG_R17 = 17;
+   public static final int UC_RH850_REG_R18 = 18;
+   public static final int UC_RH850_REG_R19 = 19;
+   public static final int UC_RH850_REG_R20 = 20;
+   public static final int UC_RH850_REG_R21 = 21;
+   public static final int UC_RH850_REG_R22 = 22;
+   public static final int UC_RH850_REG_R23 = 23;
+   public static final int UC_RH850_REG_R24 = 24;
+   public static final int UC_RH850_REG_R25 = 25;
+   public static final int UC_RH850_REG_R26 = 26;
+   public static final int UC_RH850_REG_R27 = 27;
+   public static final int UC_RH850_REG_R28 = 28;
+   public static final int UC_RH850_REG_R29 = 29;
+   public static final int UC_RH850_REG_R30 = 30;
+   public static final int UC_RH850_REG_R31 = 31;
+
+// RH850 system registers, selection ID 0
+   public static final int UC_RH850_REG_EIPC = 32;
+   public static final int UC_RH850_REG_EIPSW = 33;
+   public static final int UC_RH850_REG_FEPC = 34;
+   public static final int UC_RH850_REG_FEPSW = 35;
+   public static final int UC_RH850_REG_ECR = 36;
+   public static final int UC_RH850_REG_PSW = 37;
+   public static final int UC_RH850_REG_FPSR = 38;
+   public static final int UC_RH850_REG_FPEPC = 39;
+   public static final int UC_RH850_REG_FPST = 40;
+   public static final int UC_RH850_REG_FPCC = 41;
+   public static final int UC_RH850_REG_FPCFG = 42;
+   public static final int UC_RH850_REG_FPEC = 43;
+   public static final int UC_RH850_REG_EIIC = 45;
+   public static final int UC_RH850_REG_FEIC = 46;
+   public static final int UC_RH850_REG_CTPC = 48;
+   public static final int UC_RH850_REG_CTPSW = 49;
+   public static final int UC_RH850_REG_CTBP = 52;
+   public static final int UC_RH850_REG_EIWR = 60;
+   public static final int UC_RH850_REG_FEWR = 61;
+   public static final int UC_RH850_REG_BSEL = 63;
+
+// RH850 system regusters, selection ID 1
+   public static final int UC_RH850_REG_MCFG0 = 64;
+   public static final int UC_RH850_REG_RBASE = 65;
+   public static final int UC_RH850_REG_EBASE = 66;
+   public static final int UC_RH850_REG_INTBP = 67;
+   public static final int UC_RH850_REG_MCTL = 68;
+   public static final int UC_RH850_REG_PID = 69;
+   public static final int UC_RH850_REG_SCCFG = 75;
+   public static final int UC_RH850_REG_SCBP = 76;
+
+// RH850 system registers, selection ID 2
+   public static final int UC_RH850_REG_HTCFG0 = 96;
+   public static final int UC_RH850_REG_MEA = 102;
+   public static final int UC_RH850_REG_ASID = 103;
+   public static final int UC_RH850_REG_MEI = 104;
+   public static final int UC_RH850_REG_PC = 288;
+   public static final int UC_RH850_REG_ENDING = 289;
+
+// RH8509 Registers aliases.
+
+   public static final int UC_RH850_REG_ZERO = 0;
+   public static final int UC_RH850_REG_SP = 3;
+   public static final int UC_RH850_REG_EP = 30;
+   public static final int UC_RH850_REG_LP = 31;
+
+}
diff --git a/bindings/java/src/main/java/unicorn/UnicornConst.java b/bindings/java/src/main/java/unicorn/UnicornConst.java
index 8ab6fdb174..ac91590da1 100644
--- a/bindings/java/src/main/java/unicorn/UnicornConst.java
+++ b/bindings/java/src/main/java/unicorn/UnicornConst.java
@@ -25,7 +25,8 @@ public interface UnicornConst {
     public static final int UC_ARCH_RISCV = 8;
     public static final int UC_ARCH_S390X = 9;
     public static final int UC_ARCH_TRICORE = 10;
-    public static final int UC_ARCH_MAX = 11;
+    public static final int UC_ARCH_RH850 = 11;
+    public static final int UC_ARCH_MAX = 12;
 
     public static final int UC_MODE_LITTLE_ENDIAN = 0;
     public static final int UC_MODE_BIG_ENDIAN = 1073741824;
@@ -52,6 +53,7 @@ public interface UnicornConst {
     public static final int UC_MODE_SPARC32 = 4;
     public static final int UC_MODE_SPARC64 = 8;
     public static final int UC_MODE_V9 = 16;
+    public static final int UC_MODE_RH850 = 4;
     public static final int UC_MODE_RISCV32 = 4;
     public static final int UC_MODE_RISCV64 = 8;
 
diff --git a/bindings/pascal/unicorn/Rh850Const.pas b/bindings/pascal/unicorn/Rh850Const.pas
new file mode 100644
index 0000000000..c405b3c464
--- /dev/null
+++ b/bindings/pascal/unicorn/Rh850Const.pas
@@ -0,0 +1,99 @@
+// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
+
+unit Rh850Const;
+
+interface
+
+const  UC_RH850_SYSREG_SELID0 = 32;
+  UC_RH850_SYSREG_SELID1 = 64;
+  UC_RH850_SYSREG_SELID2 = 96;
+  UC_RH850_SYSREG_SELID3 = 128;
+  UC_RH850_SYSREG_SELID4 = 160;
+  UC_RH850_SYSREG_SELID5 = 192;
+  UC_RH850_SYSREG_SELID6 = 224;
+  UC_RH850_SYSREG_SELID7 = 256;
+
+// RH850 global purpose registers
+
+  UC_RH850_REG_R0 = 0;
+  UC_RH850_REG_R1 = 1;
+  UC_RH850_REG_R2 = 2;
+  UC_RH850_REG_R3 = 3;
+  UC_RH850_REG_R4 = 4;
+  UC_RH850_REG_R5 = 5;
+  UC_RH850_REG_R6 = 6;
+  UC_RH850_REG_R7 = 7;
+  UC_RH850_REG_R8 = 8;
+  UC_RH850_REG_R9 = 9;
+  UC_RH850_REG_R10 = 10;
+  UC_RH850_REG_R11 = 11;
+  UC_RH850_REG_R12 = 12;
+  UC_RH850_REG_R13 = 13;
+  UC_RH850_REG_R14 = 14;
+  UC_RH850_REG_R15 = 15;
+  UC_RH850_REG_R16 = 16;
+  UC_RH850_REG_R17 = 17;
+  UC_RH850_REG_R18 = 18;
+  UC_RH850_REG_R19 = 19;
+  UC_RH850_REG_R20 = 20;
+  UC_RH850_REG_R21 = 21;
+  UC_RH850_REG_R22 = 22;
+  UC_RH850_REG_R23 = 23;
+  UC_RH850_REG_R24 = 24;
+  UC_RH850_REG_R25 = 25;
+  UC_RH850_REG_R26 = 26;
+  UC_RH850_REG_R27 = 27;
+  UC_RH850_REG_R28 = 28;
+  UC_RH850_REG_R29 = 29;
+  UC_RH850_REG_R30 = 30;
+  UC_RH850_REG_R31 = 31;
+
+// RH850 system registers, selection ID 0
+  UC_RH850_REG_EIPC = 32;
+  UC_RH850_REG_EIPSW = 33;
+  UC_RH850_REG_FEPC = 34;
+  UC_RH850_REG_FEPSW = 35;
+  UC_RH850_REG_ECR = 36;
+  UC_RH850_REG_PSW = 37;
+  UC_RH850_REG_FPSR = 38;
+  UC_RH850_REG_FPEPC = 39;
+  UC_RH850_REG_FPST = 40;
+  UC_RH850_REG_FPCC = 41;
+  UC_RH850_REG_FPCFG = 42;
+  UC_RH850_REG_FPEC = 43;
+  UC_RH850_REG_EIIC = 45;
+  UC_RH850_REG_FEIC = 46;
+  UC_RH850_REG_CTPC = 48;
+  UC_RH850_REG_CTPSW = 49;
+  UC_RH850_REG_CTBP = 52;
+  UC_RH850_REG_EIWR = 60;
+  UC_RH850_REG_FEWR = 61;
+  UC_RH850_REG_BSEL = 63;
+
+// RH850 system regusters, selection ID 1
+  UC_RH850_REG_MCFG0 = 64;
+  UC_RH850_REG_RBASE = 65;
+  UC_RH850_REG_EBASE = 66;
+  UC_RH850_REG_INTBP = 67;
+  UC_RH850_REG_MCTL = 68;
+  UC_RH850_REG_PID = 69;
+  UC_RH850_REG_SCCFG = 75;
+  UC_RH850_REG_SCBP = 76;
+
+// RH850 system registers, selection ID 2
+  UC_RH850_REG_HTCFG0 = 96;
+  UC_RH850_REG_MEA = 102;
+  UC_RH850_REG_ASID = 103;
+  UC_RH850_REG_MEI = 104;
+  UC_RH850_REG_PC = 288;
+  UC_RH850_REG_ENDING = 289;
+
+// RH8509 Registers aliases.
+
+  UC_RH850_REG_ZERO = 0;
+  UC_RH850_REG_SP = 3;
+  UC_RH850_REG_EP = 30;
+  UC_RH850_REG_LP = 31;
+
+implementation
+end.
\ No newline at end of file
diff --git a/bindings/pascal/unicorn/UnicornConst.pas b/bindings/pascal/unicorn/UnicornConst.pas
index 8b38e8e034..a959c25703 100644
--- a/bindings/pascal/unicorn/UnicornConst.pas
+++ b/bindings/pascal/unicorn/UnicornConst.pas
@@ -26,7 +26,8 @@ interface
   UC_ARCH_RISCV = 8;
   UC_ARCH_S390X = 9;
   UC_ARCH_TRICORE = 10;
-  UC_ARCH_MAX = 11;
+  UC_ARCH_RH850 = 11;
+  UC_ARCH_MAX = 12;
 
   UC_MODE_LITTLE_ENDIAN = 0;
   UC_MODE_BIG_ENDIAN = 1073741824;
@@ -53,6 +54,7 @@ interface
   UC_MODE_SPARC32 = 4;
   UC_MODE_SPARC64 = 8;
   UC_MODE_V9 = 16;
+  UC_MODE_RH850 = 4;
   UC_MODE_RISCV32 = 4;
   UC_MODE_RISCV64 = 8;
 
diff --git a/bindings/python/sample_rh850.py b/bindings/python/sample_rh850.py
new file mode 100644
index 0000000000..294d76ff2b
--- /dev/null
+++ b/bindings/python/sample_rh850.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+# Sample code for RH850 of Unicorn. Damien Cauquil <dcauquil@quarkslab.com>
+#
+
+from __future__ import print_function
+from unicorn import *
+from unicorn.rh850_const import *
+
+
+'''
+ 0  01 0e 06 addi 6, r1, r1
+ 4  00 c1 11 add  r1, r2
+'''
+RH850_CODE = b"\x01\x0e\x06\x00\xc1\x11"
+
+# memory address where emulation starts
+ADDRESS    = 0x10000
+
+
+# callback for tracing basic blocks
+def hook_block(uc, address, size, user_data):
+    print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size))
+
+
+# callback for tracing instructions
+def hook_code(uc, address, size, user_data):
+    print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" %(address, size))
+
+
+# Test RH850
+def test_rh850():
+    print("Emulate RH850 code")
+    try:
+        # Initialize emulator in RISCV32 mode
+        mu = Uc(UC_ARCH_RH850, 0)
+
+        # map 2MB memory for this emulation
+        mu.mem_map(ADDRESS, 2 * 1024 * 1024)
+
+        # write machine code to be emulated to memory
+        mu.mem_write(ADDRESS, RH850_CODE)
+
+        # initialize machine registers
+        mu.reg_write(UC_RH850_REG_R1, 0x1234)
+        mu.reg_write(UC_RH850_REG_R2, 0x7890)
+
+        # tracing all basic blocks with customized callback
+        mu.hook_add(UC_HOOK_BLOCK, hook_block)
+
+        # tracing all instructions with customized callback
+        mu.hook_add(UC_HOOK_CODE, hook_code)
+
+        # emulate machine code in infinite time
+        mu.emu_start(ADDRESS, ADDRESS + len(RH850_CODE))
+
+        # now print out some registers
+        print(">>> Emulation done. Below is the CPU context")
+
+        r1 = mu.reg_read(UC_RH850_REG_R1)
+        r2 = mu.reg_read(UC_RH850_REG_R2)
+        print(">>> R1 = 0x%x" % r1)
+        print(">>> R2 = 0x%x" % r2)
+
+    except UcError as e:
+        print("ERROR: %s" % e)
+
+
+if __name__ == '__main__':
+    test_rh850()
+
diff --git a/bindings/python/unicorn/rh850_const.py b/bindings/python/unicorn/rh850_const.py
new file mode 100644
index 0000000000..6985d85e4f
--- /dev/null
+++ b/bindings/python/unicorn/rh850_const.py
@@ -0,0 +1,91 @@
+# For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [rh850_const.py]
+UC_RH850_SYSREG_SELID0 = 32
+UC_RH850_SYSREG_SELID1 = 64
+UC_RH850_SYSREG_SELID2 = 96
+UC_RH850_SYSREG_SELID3 = 128
+UC_RH850_SYSREG_SELID4 = 160
+UC_RH850_SYSREG_SELID5 = 192
+UC_RH850_SYSREG_SELID6 = 224
+UC_RH850_SYSREG_SELID7 = 256
+
+# RH850 global purpose registers
+
+UC_RH850_REG_R0 = 0
+UC_RH850_REG_R1 = 1
+UC_RH850_REG_R2 = 2
+UC_RH850_REG_R3 = 3
+UC_RH850_REG_R4 = 4
+UC_RH850_REG_R5 = 5
+UC_RH850_REG_R6 = 6
+UC_RH850_REG_R7 = 7
+UC_RH850_REG_R8 = 8
+UC_RH850_REG_R9 = 9
+UC_RH850_REG_R10 = 10
+UC_RH850_REG_R11 = 11
+UC_RH850_REG_R12 = 12
+UC_RH850_REG_R13 = 13
+UC_RH850_REG_R14 = 14
+UC_RH850_REG_R15 = 15
+UC_RH850_REG_R16 = 16
+UC_RH850_REG_R17 = 17
+UC_RH850_REG_R18 = 18
+UC_RH850_REG_R19 = 19
+UC_RH850_REG_R20 = 20
+UC_RH850_REG_R21 = 21
+UC_RH850_REG_R22 = 22
+UC_RH850_REG_R23 = 23
+UC_RH850_REG_R24 = 24
+UC_RH850_REG_R25 = 25
+UC_RH850_REG_R26 = 26
+UC_RH850_REG_R27 = 27
+UC_RH850_REG_R28 = 28
+UC_RH850_REG_R29 = 29
+UC_RH850_REG_R30 = 30
+UC_RH850_REG_R31 = 31
+
+# RH850 system registers, selection ID 0
+UC_RH850_REG_EIPC = 32
+UC_RH850_REG_EIPSW = 33
+UC_RH850_REG_FEPC = 34
+UC_RH850_REG_FEPSW = 35
+UC_RH850_REG_ECR = 36
+UC_RH850_REG_PSW = 37
+UC_RH850_REG_FPSR = 38
+UC_RH850_REG_FPEPC = 39
+UC_RH850_REG_FPST = 40
+UC_RH850_REG_FPCC = 41
+UC_RH850_REG_FPCFG = 42
+UC_RH850_REG_FPEC = 43
+UC_RH850_REG_EIIC = 45
+UC_RH850_REG_FEIC = 46
+UC_RH850_REG_CTPC = 48
+UC_RH850_REG_CTPSW = 49
+UC_RH850_REG_CTBP = 52
+UC_RH850_REG_EIWR = 60
+UC_RH850_REG_FEWR = 61
+UC_RH850_REG_BSEL = 63
+
+# RH850 system regusters, selection ID 1
+UC_RH850_REG_MCFG0 = 64
+UC_RH850_REG_RBASE = 65
+UC_RH850_REG_EBASE = 66
+UC_RH850_REG_INTBP = 67
+UC_RH850_REG_MCTL = 68
+UC_RH850_REG_PID = 69
+UC_RH850_REG_SCCFG = 75
+UC_RH850_REG_SCBP = 76
+
+# RH850 system registers, selection ID 2
+UC_RH850_REG_HTCFG0 = 96
+UC_RH850_REG_MEA = 102
+UC_RH850_REG_ASID = 103
+UC_RH850_REG_MEI = 104
+UC_RH850_REG_PC = 288
+UC_RH850_REG_ENDING = 289
+
+# RH8509 Registers aliases.
+
+UC_RH850_REG_ZERO = 0
+UC_RH850_REG_SP = 3
+UC_RH850_REG_EP = 30
+UC_RH850_REG_LP = 31
diff --git a/bindings/python/unicorn/unicorn_const.py b/bindings/python/unicorn/unicorn_const.py
index 64247899e6..885a5eb910 100644
--- a/bindings/python/unicorn/unicorn_const.py
+++ b/bindings/python/unicorn/unicorn_const.py
@@ -21,7 +21,8 @@
 UC_ARCH_RISCV = 8
 UC_ARCH_S390X = 9
 UC_ARCH_TRICORE = 10
-UC_ARCH_MAX = 11
+UC_ARCH_RH850 = 11
+UC_ARCH_MAX = 12
 
 UC_MODE_LITTLE_ENDIAN = 0
 UC_MODE_BIG_ENDIAN = 1073741824
@@ -48,6 +49,7 @@
 UC_MODE_SPARC32 = 4
 UC_MODE_SPARC64 = 8
 UC_MODE_V9 = 16
+UC_MODE_RH850 = 4
 UC_MODE_RISCV32 = 4
 UC_MODE_RISCV64 = 8
 
diff --git a/bindings/ruby/unicorn_gem/lib/unicorn_engine/rh850_const.rb b/bindings/ruby/unicorn_gem/lib/unicorn_engine/rh850_const.rb
new file mode 100644
index 0000000000..40629b9883
--- /dev/null
+++ b/bindings/ruby/unicorn_gem/lib/unicorn_engine/rh850_const.rb
@@ -0,0 +1,94 @@
+# For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [rh850_const.rb]
+
+module UnicornEngine
+	UC_RH850_SYSREG_SELID0 = 32
+	UC_RH850_SYSREG_SELID1 = 64
+	UC_RH850_SYSREG_SELID2 = 96
+	UC_RH850_SYSREG_SELID3 = 128
+	UC_RH850_SYSREG_SELID4 = 160
+	UC_RH850_SYSREG_SELID5 = 192
+	UC_RH850_SYSREG_SELID6 = 224
+	UC_RH850_SYSREG_SELID7 = 256
+
+# RH850 global purpose registers
+
+	UC_RH850_REG_R0 = 0
+	UC_RH850_REG_R1 = 1
+	UC_RH850_REG_R2 = 2
+	UC_RH850_REG_R3 = 3
+	UC_RH850_REG_R4 = 4
+	UC_RH850_REG_R5 = 5
+	UC_RH850_REG_R6 = 6
+	UC_RH850_REG_R7 = 7
+	UC_RH850_REG_R8 = 8
+	UC_RH850_REG_R9 = 9
+	UC_RH850_REG_R10 = 10
+	UC_RH850_REG_R11 = 11
+	UC_RH850_REG_R12 = 12
+	UC_RH850_REG_R13 = 13
+	UC_RH850_REG_R14 = 14
+	UC_RH850_REG_R15 = 15
+	UC_RH850_REG_R16 = 16
+	UC_RH850_REG_R17 = 17
+	UC_RH850_REG_R18 = 18
+	UC_RH850_REG_R19 = 19
+	UC_RH850_REG_R20 = 20
+	UC_RH850_REG_R21 = 21
+	UC_RH850_REG_R22 = 22
+	UC_RH850_REG_R23 = 23
+	UC_RH850_REG_R24 = 24
+	UC_RH850_REG_R25 = 25
+	UC_RH850_REG_R26 = 26
+	UC_RH850_REG_R27 = 27
+	UC_RH850_REG_R28 = 28
+	UC_RH850_REG_R29 = 29
+	UC_RH850_REG_R30 = 30
+	UC_RH850_REG_R31 = 31
+
+# RH850 system registers, selection ID 0
+	UC_RH850_REG_EIPC = 32
+	UC_RH850_REG_EIPSW = 33
+	UC_RH850_REG_FEPC = 34
+	UC_RH850_REG_FEPSW = 35
+	UC_RH850_REG_ECR = 36
+	UC_RH850_REG_PSW = 37
+	UC_RH850_REG_FPSR = 38
+	UC_RH850_REG_FPEPC = 39
+	UC_RH850_REG_FPST = 40
+	UC_RH850_REG_FPCC = 41
+	UC_RH850_REG_FPCFG = 42
+	UC_RH850_REG_FPEC = 43
+	UC_RH850_REG_EIIC = 45
+	UC_RH850_REG_FEIC = 46
+	UC_RH850_REG_CTPC = 48
+	UC_RH850_REG_CTPSW = 49
+	UC_RH850_REG_CTBP = 52
+	UC_RH850_REG_EIWR = 60
+	UC_RH850_REG_FEWR = 61
+	UC_RH850_REG_BSEL = 63
+
+# RH850 system regusters, selection ID 1
+	UC_RH850_REG_MCFG0 = 64
+	UC_RH850_REG_RBASE = 65
+	UC_RH850_REG_EBASE = 66
+	UC_RH850_REG_INTBP = 67
+	UC_RH850_REG_MCTL = 68
+	UC_RH850_REG_PID = 69
+	UC_RH850_REG_SCCFG = 75
+	UC_RH850_REG_SCBP = 76
+
+# RH850 system registers, selection ID 2
+	UC_RH850_REG_HTCFG0 = 96
+	UC_RH850_REG_MEA = 102
+	UC_RH850_REG_ASID = 103
+	UC_RH850_REG_MEI = 104
+	UC_RH850_REG_PC = 288
+	UC_RH850_REG_ENDING = 289
+
+# RH8509 Registers aliases.
+
+	UC_RH850_REG_ZERO = 0
+	UC_RH850_REG_SP = 3
+	UC_RH850_REG_EP = 30
+	UC_RH850_REG_LP = 31
+end
\ No newline at end of file
diff --git a/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb b/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb
index 8eaf2c3633..f022e70c81 100644
--- a/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb
+++ b/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb
@@ -23,7 +23,8 @@ module UnicornEngine
 	UC_ARCH_RISCV = 8
 	UC_ARCH_S390X = 9
 	UC_ARCH_TRICORE = 10
-	UC_ARCH_MAX = 11
+	UC_ARCH_RH850 = 11
+	UC_ARCH_MAX = 12
 
 	UC_MODE_LITTLE_ENDIAN = 0
 	UC_MODE_BIG_ENDIAN = 1073741824
@@ -50,6 +51,7 @@ module UnicornEngine
 	UC_MODE_SPARC32 = 4
 	UC_MODE_SPARC64 = 8
 	UC_MODE_V9 = 16
+	UC_MODE_RH850 = 4
 	UC_MODE_RISCV32 = 4
 	UC_MODE_RISCV64 = 8
 
diff --git a/bindings/rust/build.rs b/bindings/rust/build.rs
index 04f5431a90..f1ea169b54 100644
--- a/bindings/rust/build.rs
+++ b/bindings/rust/build.rs
@@ -116,6 +116,9 @@ fn build_with_cmake() {
     if std::env::var("CARGO_FEATURE_ARCH_TRICORE").is_ok() {
         archs.push_str("tricore;");
     }
+    if std::env::var("CARGO_FEATURE_ARCH_RH850").is_ok() {
+        archs.push_str("rh850;");
+    }
 
     if !archs.is_empty() {
         archs.pop();
diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs
index 45962acf04..0828edf851 100644
--- a/bindings/rust/src/lib.rs
+++ b/bindings/rust/src/lib.rs
@@ -51,6 +51,7 @@ pub use crate::riscv::*;
 pub use crate::s390x::*;
 pub use crate::sparc::*;
 pub use crate::tricore::*;
+pub use crate::rh850::*;
 pub use crate::unicorn_const::*;
 pub use crate::x86::*;
 
@@ -67,6 +68,7 @@ mod riscv;
 mod s390x;
 mod sparc;
 mod tricore;
+mod rh850;
 mod x86;
 
 #[derive(Debug)]
@@ -999,6 +1001,7 @@ impl<'a, D> Unicorn<'a, D> {
             Arch::RISCV => RegisterRISCV::PC as i32,
             Arch::S390X => RegisterS390X::PC as i32,
             Arch::TRICORE => RegisterTRICORE::PC as i32,
+            Arch::RH850 => RegisterRH850::PC as i32,
             Arch::MAX => panic!("Illegal Arch specified"),
         };
         self.reg_read(reg)
@@ -1022,6 +1025,7 @@ impl<'a, D> Unicorn<'a, D> {
             Arch::RISCV => RegisterRISCV::PC as i32,
             Arch::S390X => RegisterS390X::PC as i32,
             Arch::TRICORE => RegisterTRICORE::PC as i32,
+            Arch::RH850 => RegisterRH850::PC as i32,
             Arch::MAX => panic!("Illegal Arch specified"),
         };
         self.reg_write(reg, value)
diff --git a/bindings/rust/src/rh850.rs b/bindings/rust/src/rh850.rs
new file mode 100644
index 0000000000..92e8a16a4a
--- /dev/null
+++ b/bindings/rust/src/rh850.rs
@@ -0,0 +1,119 @@
+#![allow(non_camel_case_types)]
+
+// RH850 registers
+#[repr(C)]
+#[derive(PartialEq, Debug, Clone, Copy)]
+pub enum RegisterRH850 {
+    INVALID = -1,
+
+    // General purpose registers
+    R0 = 0,
+    R1 = 1,
+    R2 = 2,
+    R3 = 3,
+    R4 = 4,
+    R5 = 5,
+    R6 = 6,
+    R7 = 7,
+    R8 = 8,
+    R9 = 9,
+    R10 = 10,
+    R11 = 11,
+    R12 = 12,
+    R13 = 13,
+    R14 = 14,
+    R15 = 15,
+    R16 = 16,
+    R17 = 17,
+    R18 = 18,
+    R19 = 19,
+    R20 = 20,
+    R21 = 21,
+    R22 = 22,
+    R23 = 23,
+    R24 = 24,
+    R25 = 25,
+    R26 = 26,
+    R27 = 27,
+    R28 = 28,
+    R29 = 29,
+    R30 = 30,
+    R31 = 31,
+
+    // System registers
+    EIPC = 32,
+    EIPSW = 33,
+    FEPC = 34,
+    FEPSW = 35,
+    ECR = 36,
+    PSW = 37,
+    FPSR = 38,
+    FPEPC = 39,
+    FPST = 40,
+    FPCC = 41,
+    FPCFG = 42,
+    FPEC = 43,
+    EIIC = 45,
+    FEIC = 46,
+    CTPC = 48,
+    CTPSW = 49,
+    CTBP = 52,
+    EIWR = 60,
+    FEWR = 61,
+    BSEL = 63,
+
+    // system registers, selection ID 1
+    MCFG0 = 64,
+    RBASE = 65,
+    EBASE = 66,
+    INTBP = 67,
+    MCTL = 68,
+    PID = 69,
+    SCCFG = 75,
+    SCBP = 76,
+
+    // system registers, selection ID 2
+    HTCFG0 = 96,
+    MEA = 102,
+    ASID = 103,
+    MEI = 104,
+    PC = 288,
+
+    ENDING = 289,
+}
+
+impl RegisterRH850 {
+    // Alias registers
+    // (assoc) ZERO = 0,
+    // (assoc) SP = 3,
+    // (assoc) EP = 30,
+    // (assoc) LP = 31,
+    pub const ZERO: RegisterRH850 = RegisterRH850::R0;
+    pub const SP: RegisterRH850 = RegisterRH850::R3;
+    pub const EP: RegisterRH850 = RegisterRH850::R30;
+    pub const LP: RegisterRH850 = RegisterRH850::R31;
+}
+
+impl From<RegisterRH850> for i32 {
+    fn from(r: RegisterRH850) -> Self {
+        r as i32
+    }
+}
+
+#[repr(i32)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub enum RH850CpuModel {
+    UC_CPU_RH850_ANY = 0,
+}
+
+impl From<RH850CpuModel> for i32 {
+    fn from(value: RH850CpuModel) -> Self {
+        value as i32
+    }
+}
+
+impl From<&RH850CpuModel> for i32 {
+    fn from(value: &RH850CpuModel) -> Self {
+        (*value) as i32
+    }
+}
\ No newline at end of file
diff --git a/bindings/rust/src/unicorn_const.rs b/bindings/rust/src/unicorn_const.rs
index 5f8c80fd4a..59f38a6b7f 100644
--- a/bindings/rust/src/unicorn_const.rs
+++ b/bindings/rust/src/unicorn_const.rs
@@ -181,7 +181,8 @@ pub enum Arch {
     RISCV   = 8,
     S390X   = 9,
     TRICORE = 10,
-    MAX     = 11,
+    RH850   = 11,
+    MAX     = 12,
 }
 
 impl TryFrom<usize> for Arch {
@@ -199,6 +200,7 @@ impl TryFrom<usize> for Arch {
             x if x == Self::RISCV as usize => Ok(Self::RISCV),
             x if x == Self::S390X as usize => Ok(Self::S390X),
             x if x == Self::TRICORE as usize => Ok(Self::TRICORE),
+            x if x == Self::RH850 as usize => Ok(Self::RH850),
             x if x == Self::MAX as usize => Ok(Self::MAX),
             _ => Err(uc_error::ARCH),
         }
@@ -234,6 +236,7 @@ bitflags! {
         const SPARC32 = Self::MIPS32.bits();
         const SPARC64 = Self::MIPS64.bits();
         const V9 = Self::THUMB.bits();
+        const RH850 = 4;
         const RISCV32 = Self::MIPS32.bits();
         const RISCV64 = Self::MIPS64.bits();
     }
diff --git a/bindings/zig/unicorn/rh850_const.zig b/bindings/zig/unicorn/rh850_const.zig
new file mode 100644
index 0000000000..3b965c6333
--- /dev/null
+++ b/bindings/zig/unicorn/rh850_const.zig
@@ -0,0 +1,95 @@
+// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
+
+pub const rh850Const = enum(c_int) {
+	RH850_SYSREG_SELID0 = 32,
+	RH850_SYSREG_SELID1 = 64,
+	RH850_SYSREG_SELID2 = 96,
+	RH850_SYSREG_SELID3 = 128,
+	RH850_SYSREG_SELID4 = 160,
+	RH850_SYSREG_SELID5 = 192,
+	RH850_SYSREG_SELID6 = 224,
+	RH850_SYSREG_SELID7 = 256,
+
+// RH850 global purpose registers
+
+	RH850_REG_R0 = 0,
+	RH850_REG_R1 = 1,
+	RH850_REG_R2 = 2,
+	RH850_REG_R3 = 3,
+	RH850_REG_R4 = 4,
+	RH850_REG_R5 = 5,
+	RH850_REG_R6 = 6,
+	RH850_REG_R7 = 7,
+	RH850_REG_R8 = 8,
+	RH850_REG_R9 = 9,
+	RH850_REG_R10 = 10,
+	RH850_REG_R11 = 11,
+	RH850_REG_R12 = 12,
+	RH850_REG_R13 = 13,
+	RH850_REG_R14 = 14,
+	RH850_REG_R15 = 15,
+	RH850_REG_R16 = 16,
+	RH850_REG_R17 = 17,
+	RH850_REG_R18 = 18,
+	RH850_REG_R19 = 19,
+	RH850_REG_R20 = 20,
+	RH850_REG_R21 = 21,
+	RH850_REG_R22 = 22,
+	RH850_REG_R23 = 23,
+	RH850_REG_R24 = 24,
+	RH850_REG_R25 = 25,
+	RH850_REG_R26 = 26,
+	RH850_REG_R27 = 27,
+	RH850_REG_R28 = 28,
+	RH850_REG_R29 = 29,
+	RH850_REG_R30 = 30,
+	RH850_REG_R31 = 31,
+
+// RH850 system registers, selection ID 0
+	RH850_REG_EIPC = 32,
+	RH850_REG_EIPSW = 33,
+	RH850_REG_FEPC = 34,
+	RH850_REG_FEPSW = 35,
+	RH850_REG_ECR = 36,
+	RH850_REG_PSW = 37,
+	RH850_REG_FPSR = 38,
+	RH850_REG_FPEPC = 39,
+	RH850_REG_FPST = 40,
+	RH850_REG_FPCC = 41,
+	RH850_REG_FPCFG = 42,
+	RH850_REG_FPEC = 43,
+	RH850_REG_EIIC = 45,
+	RH850_REG_FEIC = 46,
+	RH850_REG_CTPC = 48,
+	RH850_REG_CTPSW = 49,
+	RH850_REG_CTBP = 52,
+	RH850_REG_EIWR = 60,
+	RH850_REG_FEWR = 61,
+	RH850_REG_BSEL = 63,
+
+// RH850 system regusters, selection ID 1
+	RH850_REG_MCFG0 = 64,
+	RH850_REG_RBASE = 65,
+	RH850_REG_EBASE = 66,
+	RH850_REG_INTBP = 67,
+	RH850_REG_MCTL = 68,
+	RH850_REG_PID = 69,
+	RH850_REG_SCCFG = 75,
+	RH850_REG_SCBP = 76,
+
+// RH850 system registers, selection ID 2
+	RH850_REG_HTCFG0 = 96,
+	RH850_REG_MEA = 102,
+	RH850_REG_ASID = 103,
+	RH850_REG_MEI = 104,
+	RH850_REG_PC = 288,
+	RH850_REG_ENDING = 289,
+
+// RH8509 Registers aliases.
+
+	RH850_REG_ZERO = 0,
+	RH850_REG_SP = 3,
+	RH850_REG_EP = 30,
+	RH850_REG_LP = 31,
+
+};
diff --git a/bindings/zig/unicorn/unicorn_const.zig b/bindings/zig/unicorn/unicorn_const.zig
index afebcd76c3..fb2ee6add8 100644
--- a/bindings/zig/unicorn/unicorn_const.zig
+++ b/bindings/zig/unicorn/unicorn_const.zig
@@ -23,7 +23,8 @@ pub const unicornConst = enum(c_int) {
 	ARCH_RISCV = 8,
 	ARCH_S390X = 9,
 	ARCH_TRICORE = 10,
-	ARCH_MAX = 11,
+	ARCH_RH850 = 11,
+	ARCH_MAX = 12,
 
 	MODE_LITTLE_ENDIAN = 0,
 	MODE_BIG_ENDIAN = 1073741824,
@@ -50,6 +51,7 @@ pub const unicornConst = enum(c_int) {
 	MODE_SPARC32 = 4,
 	MODE_SPARC64 = 8,
 	MODE_V9 = 16,
+	MODE_RH850 = 4,
 	MODE_RISCV32 = 4,
 	MODE_RISCV64 = 8,
 
@@ -75,6 +77,7 @@ pub const unicornConst = enum(c_int) {
 	ERR_HOOK_EXIST = 19,
 	ERR_RESOURCE = 20,
 	ERR_EXCEPTION = 21,
+	ERR_OVERFLOW = 22,
 	MEM_READ = 16,
 	MEM_WRITE = 17,
 	MEM_FETCH = 18,
@@ -140,11 +143,15 @@ pub const unicornConst = enum(c_int) {
 	CTL_TB_FLUSH = 10,
 	CTL_TLB_FLUSH = 11,
 	CTL_TLB_TYPE = 12,
+	CTL_TCG_BUFFER_SIZE = 13,
+	CTL_CONTEXT_MODE = 14,
 
 	PROT_NONE = 0,
 	PROT_READ = 1,
 	PROT_WRITE = 2,
 	PROT_EXEC = 4,
 	PROT_ALL = 7,
+	CTL_CONTEXT_CPU = 1,
+	CTL_CONTEXT_MEMORY = 2,
 
 };
diff --git a/include/unicorn/rh850.h b/include/unicorn/rh850.h
new file mode 100644
index 0000000000..963e0bc042
--- /dev/null
+++ b/include/unicorn/rh850.h
@@ -0,0 +1,111 @@
+/* Unicorn Engine */
+/* By Damien Cauquil <dcauquil@quarkslab.com>, 2023 */
+
+#ifndef UNICORN_RH850_H
+#define UNICORN_RH850_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4201)
+#endif
+
+#define UC_RH850_SYSREG_SELID0   32
+#define UC_RH850_SYSREG_SELID1   64
+#define UC_RH850_SYSREG_SELID2   96
+#define UC_RH850_SYSREG_SELID3   128
+#define UC_RH850_SYSREG_SELID4   160
+#define UC_RH850_SYSREG_SELID5   192
+#define UC_RH850_SYSREG_SELID6   224
+#define UC_RH850_SYSREG_SELID7   256
+
+//> RH850 global purpose registers
+typedef enum uc_rh850_reg {
+    UC_RH850_REG_R0 = 0,
+    UC_RH850_REG_R1,
+    UC_RH850_REG_R2,
+    UC_RH850_REG_R3,
+    UC_RH850_REG_R4,
+    UC_RH850_REG_R5,
+    UC_RH850_REG_R6,
+    UC_RH850_REG_R7,
+    UC_RH850_REG_R8,
+    UC_RH850_REG_R9,
+    UC_RH850_REG_R10,
+    UC_RH850_REG_R11,
+    UC_RH850_REG_R12,
+    UC_RH850_REG_R13,
+    UC_RH850_REG_R14,
+    UC_RH850_REG_R15,
+    UC_RH850_REG_R16,
+    UC_RH850_REG_R17,
+    UC_RH850_REG_R18,
+    UC_RH850_REG_R19,
+    UC_RH850_REG_R20,
+    UC_RH850_REG_R21,
+    UC_RH850_REG_R22,
+    UC_RH850_REG_R23,
+    UC_RH850_REG_R24,
+    UC_RH850_REG_R25,
+    UC_RH850_REG_R26,
+    UC_RH850_REG_R27,
+    UC_RH850_REG_R28,
+    UC_RH850_REG_R29,
+    UC_RH850_REG_R30,
+    UC_RH850_REG_R31,
+
+    //> RH850 system registers, selection ID 0
+    UC_RH850_REG_EIPC = UC_RH850_SYSREG_SELID0,
+    UC_RH850_REG_EIPSW,
+    UC_RH850_REG_FEPC,
+    UC_RH850_REG_FEPSW,
+    UC_RH850_REG_ECR,
+    UC_RH850_REG_PSW,
+    UC_RH850_REG_FPSR,
+    UC_RH850_REG_FPEPC,
+    UC_RH850_REG_FPST,
+    UC_RH850_REG_FPCC,
+    UC_RH850_REG_FPCFG,
+    UC_RH850_REG_FPEC,
+    UC_RH850_REG_EIIC = UC_RH850_SYSREG_SELID0 + 13,
+    UC_RH850_REG_FEIC,
+    UC_RH850_REG_CTPC = UC_RH850_SYSREG_SELID0 + 16,
+    UC_RH850_REG_CTPSW,
+    UC_RH850_REG_CTBP = UC_RH850_SYSREG_SELID0 + 20,
+    UC_RH850_REG_EIWR = UC_RH850_SYSREG_SELID0 + 28,
+    UC_RH850_REG_FEWR = UC_RH850_SYSREG_SELID0 + 29,
+    UC_RH850_REG_BSEL = UC_RH850_SYSREG_SELID0 + 31,
+
+    //> RH850 system regusters, selection ID 1
+    UC_RH850_REG_MCFG0 = UC_RH850_SYSREG_SELID1,
+    UC_RH850_REG_RBASE,
+    UC_RH850_REG_EBASE,
+    UC_RH850_REG_INTBP,
+    UC_RH850_REG_MCTL,
+    UC_RH850_REG_PID,
+    UC_RH850_REG_SCCFG = UC_RH850_SYSREG_SELID1 + 11,
+    UC_RH850_REG_SCBP,
+
+    //> RH850 system registers, selection ID 2
+    UC_RH850_REG_HTCFG0 = UC_RH850_SYSREG_SELID2,
+    UC_RH850_REG_MEA = UC_RH850_SYSREG_SELID2 + 6,
+    UC_RH850_REG_ASID,
+    UC_RH850_REG_MEI,
+
+    UC_RH850_REG_PC = UC_RH850_SYSREG_SELID7 + 32,
+    UC_RH850_REG_ENDING
+} uc_cpu_rh850;
+
+//> RH8509 Registers aliases.
+#define UC_RH850_REG_ZERO        UC_RH850_REG_R0
+#define UC_RH850_REG_SP          UC_RH850_REG_R3
+#define UC_RH850_REG_EP          UC_RH850_REG_R30
+#define UC_RH850_REG_LP          UC_RH850_REG_R31
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h
index 91b0019cca..0946e2afea 100644
--- a/include/unicorn/unicorn.h
+++ b/include/unicorn/unicorn.h
@@ -33,6 +33,7 @@ typedef size_t uc_hook;
 #include "mips.h"
 #include "sparc.h"
 #include "ppc.h"
+#include "rh850.h"
 #include "riscv.h"
 #include "s390x.h"
 #include "tricore.h"
@@ -106,6 +107,7 @@ typedef enum uc_arch {
     UC_ARCH_RISCV,   // RISCV architecture
     UC_ARCH_S390X,   // S390X architecture
     UC_ARCH_TRICORE, // TriCore architecture
+    UC_ARCH_RH850,   // Renesas RH850 architecture (V850e3v2)
     UC_ARCH_MAX,
 } uc_arch;
 
@@ -152,6 +154,9 @@ typedef enum uc_mode {
     UC_MODE_SPARC64 = 1 << 3, // 64-bit mode
     UC_MODE_V9 = 1 << 4,      // SparcV9 mode (currently unsupported)
 
+    // rh850
+    UC_MODE_RH850 = 1 << 2, // 32-bit mode
+
     // riscv
     UC_MODE_RISCV32 = 1 << 2, // 32-bit mode
     UC_MODE_RISCV64 = 1 << 3, // 64-bit mode
diff --git a/msvc/rh850-softmmu/config-target.h b/msvc/rh850-softmmu/config-target.h
new file mode 100644
index 0000000000..69d3c14d97
--- /dev/null
+++ b/msvc/rh850-softmmu/config-target.h
@@ -0,0 +1,6 @@
+/* Automatically generated by create_config - do not modify */
+#define TARGET_RH850 1
+#define TARGET_NAME "rh850"
+#define TARGET_RH850 1
+#define TARGET_SYSTBL_ABI common,nospu,64
+#define CONFIG_SOFTMMU 1
diff --git a/qemu/configure b/qemu/configure
index 80080d0d1d..73ffc653cc 100755
--- a/qemu/configure
+++ b/qemu/configure
@@ -858,7 +858,7 @@ QEMU_CFLAGS="$CPU_CFLAGS $QEMU_CFLAGS"
 default_target_list="aarch64-softmmu \
     arm-softmmu m68k-softmmu mips64el-softmmu mips64-softmmu mipsel-softmmu \
     mips-softmmu ppc64-softmmu ppc-softmmu sparc64-softmmu sparc-softmmu \
-    x86_64-softmmu riscv32-softmmu riscv64-softmmu s390x-softmmu \
+    x86_64-softmmu rh850-softmmu riscv32-softmmu riscv64-softmmu s390x-softmmu \
     tricore-softmmu"
 
 if test x"$show_help" = x"yes" ; then
@@ -2599,7 +2599,7 @@ config_target_mak=$target_dir/config-target.mak
 target_name=$(echo $target | cut -d '-' -f 1)
 target_aligned_only="no"
 case "$target_name" in
-  alpha|hppa|mips64el|mips64|mipsel|mips|mipsn32|mipsn32el|sh4|sh4eb|sparc|sparc64|sparc32plus|xtensa|xtensaeb)
+  alpha|hppa|mips64el|mips64|mipsel|mips|mipsn32|mipsn32el|rh850|sh4|sh4eb|sparc|sparc64|sparc32plus|xtensa|xtensaeb)
   target_aligned_only="yes"
   ;;
 esac
@@ -2715,6 +2715,11 @@ case "$target_name" in
     TARGET_SYSTBL_ABI=common,nospu,32
     echo "TARGET_ABI32=y" >> $config_target_mak
   ;;
+  rh850)
+    TARGET_ARCH=rh850
+    TARGET_ABI_DIR=rh850
+    mttcg=no              # system emulation is not supported for RH850
+  ;;
   riscv32)
     TARGET_BASE_ARCH=riscv
     TARGET_ABI_DIR=riscv
diff --git a/qemu/rh850.h b/qemu/rh850.h
new file mode 100644
index 0000000000..071393cb7c
--- /dev/null
+++ b/qemu/rh850.h
@@ -0,0 +1,1294 @@
+/* Autogen header for Unicorn Engine - DONOT MODIFY */
+#ifndef UNICORN_AUTOGEN_rh850_H
+#define UNICORN_AUTOGEN_rh850_H
+#ifndef UNICORN_ARCH_POSTFIX
+#define UNICORN_ARCH_POSTFIX _rh850
+#endif
+#define unicorn_fill_tlb unicorn_fill_tlb_rh850
+#define reg_read reg_read_rh850
+#define reg_write reg_write_rh850
+#define uc_init uc_init_rh850
+#define uc_add_inline_hook uc_add_inline_hook_rh850
+#define uc_del_inline_hook uc_del_inline_hook_rh850
+#define tb_invalidate_phys_range tb_invalidate_phys_range_rh850
+#define use_idiv_instructions use_idiv_instructions_rh850
+#define arm_arch arm_arch_rh850
+#define tb_target_set_jmp_target tb_target_set_jmp_target_rh850
+#define have_bmi1 have_bmi1_rh850
+#define have_popcnt have_popcnt_rh850
+#define have_avx1 have_avx1_rh850
+#define have_avx2 have_avx2_rh850
+#define have_isa have_isa_rh850
+#define have_altivec have_altivec_rh850
+#define have_vsx have_vsx_rh850
+#define flush_icache_range flush_icache_range_rh850
+#define s390_facilities s390_facilities_rh850
+#define tcg_dump_op tcg_dump_op_rh850
+#define tcg_dump_ops tcg_dump_ops_rh850
+#define tcg_gen_and_i64 tcg_gen_and_i64_rh850
+#define tcg_gen_discard_i64 tcg_gen_discard_i64_rh850
+#define tcg_gen_ld16s_i64 tcg_gen_ld16s_i64_rh850
+#define tcg_gen_ld16u_i64 tcg_gen_ld16u_i64_rh850
+#define tcg_gen_ld32s_i64 tcg_gen_ld32s_i64_rh850
+#define tcg_gen_ld32u_i64 tcg_gen_ld32u_i64_rh850
+#define tcg_gen_ld8s_i64 tcg_gen_ld8s_i64_rh850
+#define tcg_gen_ld8u_i64 tcg_gen_ld8u_i64_rh850
+#define tcg_gen_ld_i64 tcg_gen_ld_i64_rh850
+#define tcg_gen_mov_i64 tcg_gen_mov_i64_rh850
+#define tcg_gen_movi_i64 tcg_gen_movi_i64_rh850
+#define tcg_gen_mul_i64 tcg_gen_mul_i64_rh850
+#define tcg_gen_or_i64 tcg_gen_or_i64_rh850
+#define tcg_gen_sar_i64 tcg_gen_sar_i64_rh850
+#define tcg_gen_shl_i64 tcg_gen_shl_i64_rh850
+#define tcg_gen_shr_i64 tcg_gen_shr_i64_rh850
+#define tcg_gen_st_i64 tcg_gen_st_i64_rh850
+#define tcg_gen_xor_i64 tcg_gen_xor_i64_rh850
+#define cpu_icount_to_ns cpu_icount_to_ns_rh850
+#define cpu_is_stopped cpu_is_stopped_rh850
+#define cpu_get_ticks cpu_get_ticks_rh850
+#define cpu_get_clock cpu_get_clock_rh850
+#define cpu_resume cpu_resume_rh850
+#define qemu_init_vcpu qemu_init_vcpu_rh850
+#define cpu_stop_current cpu_stop_current_rh850
+#define resume_all_vcpus resume_all_vcpus_rh850
+#define vm_start vm_start_rh850
+#define address_space_dispatch_compact address_space_dispatch_compact_rh850
+#define flatview_translate flatview_translate_rh850
+#define address_space_translate_for_iotlb address_space_translate_for_iotlb_rh850
+#define qemu_get_cpu qemu_get_cpu_rh850
+#define cpu_address_space_init cpu_address_space_init_rh850
+#define cpu_get_address_space cpu_get_address_space_rh850
+#define cpu_exec_unrealizefn cpu_exec_unrealizefn_rh850
+#define cpu_exec_initfn cpu_exec_initfn_rh850
+#define cpu_exec_realizefn cpu_exec_realizefn_rh850
+#define tb_invalidate_phys_addr tb_invalidate_phys_addr_rh850
+#define cpu_watchpoint_insert cpu_watchpoint_insert_rh850
+#define cpu_watchpoint_remove_by_ref cpu_watchpoint_remove_by_ref_rh850
+#define cpu_watchpoint_remove_all cpu_watchpoint_remove_all_rh850
+#define cpu_watchpoint_address_matches cpu_watchpoint_address_matches_rh850
+#define cpu_breakpoint_insert cpu_breakpoint_insert_rh850
+#define cpu_breakpoint_remove cpu_breakpoint_remove_rh850
+#define cpu_breakpoint_remove_by_ref cpu_breakpoint_remove_by_ref_rh850
+#define cpu_breakpoint_remove_all cpu_breakpoint_remove_all_rh850
+#define cpu_abort cpu_abort_rh850
+#define cpu_physical_memory_test_and_clear_dirty cpu_physical_memory_test_and_clear_dirty_rh850
+#define memory_region_section_get_iotlb memory_region_section_get_iotlb_rh850
+#define flatview_add_to_dispatch flatview_add_to_dispatch_rh850
+#define qemu_ram_get_host_addr qemu_ram_get_host_addr_rh850
+#define qemu_ram_get_offset qemu_ram_get_offset_rh850
+#define qemu_ram_get_used_length qemu_ram_get_used_length_rh850
+#define qemu_ram_is_shared qemu_ram_is_shared_rh850
+#define qemu_ram_pagesize qemu_ram_pagesize_rh850
+#define qemu_ram_alloc_from_ptr qemu_ram_alloc_from_ptr_rh850
+#define qemu_ram_alloc qemu_ram_alloc_rh850
+#define qemu_ram_free qemu_ram_free_rh850
+#define qemu_map_ram_ptr qemu_map_ram_ptr_rh850
+#define qemu_ram_block_host_offset qemu_ram_block_host_offset_rh850
+#define qemu_ram_block_from_host qemu_ram_block_from_host_rh850
+#define qemu_ram_addr_from_host qemu_ram_addr_from_host_rh850
+#define cpu_check_watchpoint cpu_check_watchpoint_rh850
+#define iotlb_to_section iotlb_to_section_rh850
+#define address_space_dispatch_new address_space_dispatch_new_rh850
+#define address_space_dispatch_free address_space_dispatch_free_rh850
+#define flatview_read_continue flatview_read_continue_rh850
+#define address_space_read_full address_space_read_full_rh850
+#define address_space_write address_space_write_rh850
+#define address_space_rw address_space_rw_rh850
+#define cpu_physical_memory_rw cpu_physical_memory_rw_rh850
+#define address_space_write_rom address_space_write_rom_rh850
+#define cpu_flush_icache_range cpu_flush_icache_range_rh850
+#define cpu_exec_init_all cpu_exec_init_all_rh850
+#define address_space_access_valid address_space_access_valid_rh850
+#define address_space_map address_space_map_rh850
+#define address_space_unmap address_space_unmap_rh850
+#define cpu_physical_memory_map cpu_physical_memory_map_rh850
+#define cpu_physical_memory_unmap cpu_physical_memory_unmap_rh850
+#define cpu_memory_rw_debug cpu_memory_rw_debug_rh850
+#define qemu_target_page_size qemu_target_page_size_rh850
+#define qemu_target_page_bits qemu_target_page_bits_rh850
+#define qemu_target_page_bits_min qemu_target_page_bits_min_rh850
+#define target_words_bigendian target_words_bigendian_rh850
+#define cpu_physical_memory_is_io cpu_physical_memory_is_io_rh850
+#define ram_block_discard_range ram_block_discard_range_rh850
+#define ramblock_is_pmem ramblock_is_pmem_rh850
+#define page_size_init page_size_init_rh850
+#define set_preferred_target_page_bits set_preferred_target_page_bits_rh850
+#define finalize_target_page_bits finalize_target_page_bits_rh850
+#define cpu_outb cpu_outb_rh850
+#define cpu_outw cpu_outw_rh850
+#define cpu_outl cpu_outl_rh850
+#define cpu_inb cpu_inb_rh850
+#define cpu_inw cpu_inw_rh850
+#define cpu_inl cpu_inl_rh850
+#define memory_map memory_map_rh850
+#define memory_map_io memory_map_io_rh850
+#define memory_map_ptr memory_map_ptr_rh850
+#define memory_cow memory_cow_rh850
+#define memory_unmap memory_unmap_rh850
+#define memory_moveout memory_moveout_rh850
+#define memory_movein memory_movein_rh850
+#define memory_free memory_free_rh850
+#define flatview_unref flatview_unref_rh850
+#define address_space_get_flatview address_space_get_flatview_rh850
+#define memory_region_transaction_begin memory_region_transaction_begin_rh850
+#define memory_region_transaction_commit memory_region_transaction_commit_rh850
+#define memory_region_init memory_region_init_rh850
+#define memory_region_access_valid memory_region_access_valid_rh850
+#define memory_region_dispatch_read memory_region_dispatch_read_rh850
+#define memory_region_dispatch_write memory_region_dispatch_write_rh850
+#define memory_region_init_io memory_region_init_io_rh850
+#define memory_region_init_ram_ptr memory_region_init_ram_ptr_rh850
+#define memory_region_size memory_region_size_rh850
+#define memory_region_set_readonly memory_region_set_readonly_rh850
+#define memory_region_get_ram_ptr memory_region_get_ram_ptr_rh850
+#define memory_region_from_host memory_region_from_host_rh850
+#define memory_region_get_ram_addr memory_region_get_ram_addr_rh850
+#define memory_region_add_subregion memory_region_add_subregion_rh850
+#define memory_region_del_subregion memory_region_del_subregion_rh850
+#define memory_region_add_subregion_overlap memory_region_add_subregion_overlap_rh850
+#define memory_region_find memory_region_find_rh850
+#define memory_region_filter_subregions memory_region_filter_subregions_rh850
+#define memory_listener_register memory_listener_register_rh850
+#define memory_listener_unregister memory_listener_unregister_rh850
+#define address_space_remove_listeners address_space_remove_listeners_rh850
+#define address_space_init address_space_init_rh850
+#define address_space_destroy address_space_destroy_rh850
+#define memory_region_init_ram memory_region_init_ram_rh850
+#define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_rh850
+#define find_memory_mapping find_memory_mapping_rh850
+#define exec_inline_op exec_inline_op_rh850
+#define floatx80_default_nan floatx80_default_nan_rh850
+#define float_raise float_raise_rh850
+#define float16_is_quiet_nan float16_is_quiet_nan_rh850
+#define float16_is_signaling_nan float16_is_signaling_nan_rh850
+#define float32_is_quiet_nan float32_is_quiet_nan_rh850
+#define float32_is_signaling_nan float32_is_signaling_nan_rh850
+#define float64_is_quiet_nan float64_is_quiet_nan_rh850
+#define float64_is_signaling_nan float64_is_signaling_nan_rh850
+#define floatx80_is_quiet_nan floatx80_is_quiet_nan_rh850
+#define floatx80_is_signaling_nan floatx80_is_signaling_nan_rh850
+#define floatx80_silence_nan floatx80_silence_nan_rh850
+#define propagateFloatx80NaN propagateFloatx80NaN_rh850
+#define float128_is_quiet_nan float128_is_quiet_nan_rh850
+#define float128_is_signaling_nan float128_is_signaling_nan_rh850
+#define float128_silence_nan float128_silence_nan_rh850
+#define float16_add float16_add_rh850
+#define float16_sub float16_sub_rh850
+#define float32_add float32_add_rh850
+#define float32_sub float32_sub_rh850
+#define float64_add float64_add_rh850
+#define float64_sub float64_sub_rh850
+#define float16_mul float16_mul_rh850
+#define float32_mul float32_mul_rh850
+#define float64_mul float64_mul_rh850
+#define float16_muladd float16_muladd_rh850
+#define float32_muladd float32_muladd_rh850
+#define float64_muladd float64_muladd_rh850
+#define float16_div float16_div_rh850
+#define float32_div float32_div_rh850
+#define float64_div float64_div_rh850
+#define float16_to_float32 float16_to_float32_rh850
+#define float16_to_float64 float16_to_float64_rh850
+#define float32_to_float16 float32_to_float16_rh850
+#define float32_to_float64 float32_to_float64_rh850
+#define float64_to_float16 float64_to_float16_rh850
+#define float64_to_float32 float64_to_float32_rh850
+#define float16_round_to_int float16_round_to_int_rh850
+#define float32_round_to_int float32_round_to_int_rh850
+#define float64_round_to_int float64_round_to_int_rh850
+#define float16_to_int16_scalbn float16_to_int16_scalbn_rh850
+#define float16_to_int32_scalbn float16_to_int32_scalbn_rh850
+#define float16_to_int64_scalbn float16_to_int64_scalbn_rh850
+#define float32_to_int16_scalbn float32_to_int16_scalbn_rh850
+#define float32_to_int32_scalbn float32_to_int32_scalbn_rh850
+#define float32_to_int64_scalbn float32_to_int64_scalbn_rh850
+#define float64_to_int16_scalbn float64_to_int16_scalbn_rh850
+#define float64_to_int32_scalbn float64_to_int32_scalbn_rh850
+#define float64_to_int64_scalbn float64_to_int64_scalbn_rh850
+#define float16_to_int16 float16_to_int16_rh850
+#define float16_to_int32 float16_to_int32_rh850
+#define float16_to_int64 float16_to_int64_rh850
+#define float32_to_int16 float32_to_int16_rh850
+#define float32_to_int32 float32_to_int32_rh850
+#define float32_to_int64 float32_to_int64_rh850
+#define float64_to_int16 float64_to_int16_rh850
+#define float64_to_int32 float64_to_int32_rh850
+#define float64_to_int64 float64_to_int64_rh850
+#define float16_to_int16_round_to_zero float16_to_int16_round_to_zero_rh850
+#define float16_to_int32_round_to_zero float16_to_int32_round_to_zero_rh850
+#define float16_to_int64_round_to_zero float16_to_int64_round_to_zero_rh850
+#define float32_to_int16_round_to_zero float32_to_int16_round_to_zero_rh850
+#define float32_to_int32_round_to_zero float32_to_int32_round_to_zero_rh850
+#define float32_to_int64_round_to_zero float32_to_int64_round_to_zero_rh850
+#define float64_to_int16_round_to_zero float64_to_int16_round_to_zero_rh850
+#define float64_to_int32_round_to_zero float64_to_int32_round_to_zero_rh850
+#define float64_to_int64_round_to_zero float64_to_int64_round_to_zero_rh850
+#define float16_to_uint16_scalbn float16_to_uint16_scalbn_rh850
+#define float16_to_uint32_scalbn float16_to_uint32_scalbn_rh850
+#define float16_to_uint64_scalbn float16_to_uint64_scalbn_rh850
+#define float32_to_uint16_scalbn float32_to_uint16_scalbn_rh850
+#define float32_to_uint32_scalbn float32_to_uint32_scalbn_rh850
+#define float32_to_uint64_scalbn float32_to_uint64_scalbn_rh850
+#define float64_to_uint16_scalbn float64_to_uint16_scalbn_rh850
+#define float64_to_uint32_scalbn float64_to_uint32_scalbn_rh850
+#define float64_to_uint64_scalbn float64_to_uint64_scalbn_rh850
+#define float16_to_uint16 float16_to_uint16_rh850
+#define float16_to_uint32 float16_to_uint32_rh850
+#define float16_to_uint64 float16_to_uint64_rh850
+#define float32_to_uint16 float32_to_uint16_rh850
+#define float32_to_uint32 float32_to_uint32_rh850
+#define float32_to_uint64 float32_to_uint64_rh850
+#define float64_to_uint16 float64_to_uint16_rh850
+#define float64_to_uint32 float64_to_uint32_rh850
+#define float64_to_uint64 float64_to_uint64_rh850
+#define float16_to_uint16_round_to_zero float16_to_uint16_round_to_zero_rh850
+#define float16_to_uint32_round_to_zero float16_to_uint32_round_to_zero_rh850
+#define float16_to_uint64_round_to_zero float16_to_uint64_round_to_zero_rh850
+#define float32_to_uint16_round_to_zero float32_to_uint16_round_to_zero_rh850
+#define float32_to_uint32_round_to_zero float32_to_uint32_round_to_zero_rh850
+#define float32_to_uint64_round_to_zero float32_to_uint64_round_to_zero_rh850
+#define float64_to_uint16_round_to_zero float64_to_uint16_round_to_zero_rh850
+#define float64_to_uint32_round_to_zero float64_to_uint32_round_to_zero_rh850
+#define float64_to_uint64_round_to_zero float64_to_uint64_round_to_zero_rh850
+#define int64_to_float16_scalbn int64_to_float16_scalbn_rh850
+#define int32_to_float16_scalbn int32_to_float16_scalbn_rh850
+#define int16_to_float16_scalbn int16_to_float16_scalbn_rh850
+#define int64_to_float16 int64_to_float16_rh850
+#define int32_to_float16 int32_to_float16_rh850
+#define int16_to_float16 int16_to_float16_rh850
+#define int64_to_float32_scalbn int64_to_float32_scalbn_rh850
+#define int32_to_float32_scalbn int32_to_float32_scalbn_rh850
+#define int16_to_float32_scalbn int16_to_float32_scalbn_rh850
+#define int64_to_float32 int64_to_float32_rh850
+#define int32_to_float32 int32_to_float32_rh850
+#define int16_to_float32 int16_to_float32_rh850
+#define int64_to_float64_scalbn int64_to_float64_scalbn_rh850
+#define int32_to_float64_scalbn int32_to_float64_scalbn_rh850
+#define int16_to_float64_scalbn int16_to_float64_scalbn_rh850
+#define int64_to_float64 int64_to_float64_rh850
+#define int32_to_float64 int32_to_float64_rh850
+#define int16_to_float64 int16_to_float64_rh850
+#define uint64_to_float16_scalbn uint64_to_float16_scalbn_rh850
+#define uint32_to_float16_scalbn uint32_to_float16_scalbn_rh850
+#define uint16_to_float16_scalbn uint16_to_float16_scalbn_rh850
+#define uint64_to_float16 uint64_to_float16_rh850
+#define uint32_to_float16 uint32_to_float16_rh850
+#define uint16_to_float16 uint16_to_float16_rh850
+#define uint64_to_float32_scalbn uint64_to_float32_scalbn_rh850
+#define uint32_to_float32_scalbn uint32_to_float32_scalbn_rh850
+#define uint16_to_float32_scalbn uint16_to_float32_scalbn_rh850
+#define uint64_to_float32 uint64_to_float32_rh850
+#define uint32_to_float32 uint32_to_float32_rh850
+#define uint16_to_float32 uint16_to_float32_rh850
+#define uint64_to_float64_scalbn uint64_to_float64_scalbn_rh850
+#define uint32_to_float64_scalbn uint32_to_float64_scalbn_rh850
+#define uint16_to_float64_scalbn uint16_to_float64_scalbn_rh850
+#define uint64_to_float64 uint64_to_float64_rh850
+#define uint32_to_float64 uint32_to_float64_rh850
+#define uint16_to_float64 uint16_to_float64_rh850
+#define float16_min float16_min_rh850
+#define float16_minnum float16_minnum_rh850
+#define float16_minnummag float16_minnummag_rh850
+#define float16_max float16_max_rh850
+#define float16_maxnum float16_maxnum_rh850
+#define float16_maxnummag float16_maxnummag_rh850
+#define float32_min float32_min_rh850
+#define float32_minnum float32_minnum_rh850
+#define float32_minnummag float32_minnummag_rh850
+#define float32_max float32_max_rh850
+#define float32_maxnum float32_maxnum_rh850
+#define float32_maxnummag float32_maxnummag_rh850
+#define float64_min float64_min_rh850
+#define float64_minnum float64_minnum_rh850
+#define float64_minnummag float64_minnummag_rh850
+#define float64_max float64_max_rh850
+#define float64_maxnum float64_maxnum_rh850
+#define float64_maxnummag float64_maxnummag_rh850
+#define float16_compare float16_compare_rh850
+#define float16_compare_quiet float16_compare_quiet_rh850
+#define float32_compare float32_compare_rh850
+#define float32_compare_quiet float32_compare_quiet_rh850
+#define float64_compare float64_compare_rh850
+#define float64_compare_quiet float64_compare_quiet_rh850
+#define float16_scalbn float16_scalbn_rh850
+#define float32_scalbn float32_scalbn_rh850
+#define float64_scalbn float64_scalbn_rh850
+#define float16_sqrt float16_sqrt_rh850
+#define float32_sqrt float32_sqrt_rh850
+#define float64_sqrt float64_sqrt_rh850
+#define float16_default_nan float16_default_nan_rh850
+#define float32_default_nan float32_default_nan_rh850
+#define float64_default_nan float64_default_nan_rh850
+#define float128_default_nan float128_default_nan_rh850
+#define float16_silence_nan float16_silence_nan_rh850
+#define float32_silence_nan float32_silence_nan_rh850
+#define float64_silence_nan float64_silence_nan_rh850
+#define float16_squash_input_denormal float16_squash_input_denormal_rh850
+#define float32_squash_input_denormal float32_squash_input_denormal_rh850
+#define float64_squash_input_denormal float64_squash_input_denormal_rh850
+#define normalizeFloatx80Subnormal normalizeFloatx80Subnormal_rh850
+#define roundAndPackFloatx80 roundAndPackFloatx80_rh850
+#define normalizeRoundAndPackFloatx80 normalizeRoundAndPackFloatx80_rh850
+#define int32_to_floatx80 int32_to_floatx80_rh850
+#define int32_to_float128 int32_to_float128_rh850
+#define int64_to_floatx80 int64_to_floatx80_rh850
+#define int64_to_float128 int64_to_float128_rh850
+#define uint64_to_float128 uint64_to_float128_rh850
+#define float32_to_floatx80 float32_to_floatx80_rh850
+#define float32_to_float128 float32_to_float128_rh850
+#define float32_rem float32_rem_rh850
+#define float32_exp2 float32_exp2_rh850
+#define float32_log2 float32_log2_rh850
+#define float32_eq float32_eq_rh850
+#define float32_le float32_le_rh850
+#define float32_lt float32_lt_rh850
+#define float32_unordered float32_unordered_rh850
+#define float32_eq_quiet float32_eq_quiet_rh850
+#define float32_le_quiet float32_le_quiet_rh850
+#define float32_lt_quiet float32_lt_quiet_rh850
+#define float32_unordered_quiet float32_unordered_quiet_rh850
+#define float64_to_floatx80 float64_to_floatx80_rh850
+#define float64_to_float128 float64_to_float128_rh850
+#define float64_rem float64_rem_rh850
+#define float64_log2 float64_log2_rh850
+#define float64_eq float64_eq_rh850
+#define float64_le float64_le_rh850
+#define float64_lt float64_lt_rh850
+#define float64_unordered float64_unordered_rh850
+#define float64_eq_quiet float64_eq_quiet_rh850
+#define float64_le_quiet float64_le_quiet_rh850
+#define float64_lt_quiet float64_lt_quiet_rh850
+#define float64_unordered_quiet float64_unordered_quiet_rh850
+#define floatx80_to_int32 floatx80_to_int32_rh850
+#define floatx80_to_int32_round_to_zero floatx80_to_int32_round_to_zero_rh850
+#define floatx80_to_int64 floatx80_to_int64_rh850
+#define floatx80_to_int64_round_to_zero floatx80_to_int64_round_to_zero_rh850
+#define floatx80_to_float32 floatx80_to_float32_rh850
+#define floatx80_to_float64 floatx80_to_float64_rh850
+#define floatx80_to_float128 floatx80_to_float128_rh850
+#define floatx80_round floatx80_round_rh850
+#define floatx80_round_to_int floatx80_round_to_int_rh850
+#define floatx80_add floatx80_add_rh850
+#define floatx80_sub floatx80_sub_rh850
+#define floatx80_mul floatx80_mul_rh850
+#define floatx80_div floatx80_div_rh850
+#define floatx80_rem floatx80_rem_rh850
+#define floatx80_sqrt floatx80_sqrt_rh850
+#define floatx80_eq floatx80_eq_rh850
+#define floatx80_le floatx80_le_rh850
+#define floatx80_lt floatx80_lt_rh850
+#define floatx80_unordered floatx80_unordered_rh850
+#define floatx80_eq_quiet floatx80_eq_quiet_rh850
+#define floatx80_le_quiet floatx80_le_quiet_rh850
+#define floatx80_lt_quiet floatx80_lt_quiet_rh850
+#define floatx80_unordered_quiet floatx80_unordered_quiet_rh850
+#define float128_to_int32 float128_to_int32_rh850
+#define float128_to_int32_round_to_zero float128_to_int32_round_to_zero_rh850
+#define float128_to_int64 float128_to_int64_rh850
+#define float128_to_int64_round_to_zero float128_to_int64_round_to_zero_rh850
+#define float128_to_uint64 float128_to_uint64_rh850
+#define float128_to_uint64_round_to_zero float128_to_uint64_round_to_zero_rh850
+#define float128_to_uint32_round_to_zero float128_to_uint32_round_to_zero_rh850
+#define float128_to_uint32 float128_to_uint32_rh850
+#define float128_to_float32 float128_to_float32_rh850
+#define float128_to_float64 float128_to_float64_rh850
+#define float128_to_floatx80 float128_to_floatx80_rh850
+#define float128_round_to_int float128_round_to_int_rh850
+#define float128_add float128_add_rh850
+#define float128_sub float128_sub_rh850
+#define float128_mul float128_mul_rh850
+#define float128_div float128_div_rh850
+#define float128_rem float128_rem_rh850
+#define float128_sqrt float128_sqrt_rh850
+#define float128_eq float128_eq_rh850
+#define float128_le float128_le_rh850
+#define float128_lt float128_lt_rh850
+#define float128_unordered float128_unordered_rh850
+#define float128_eq_quiet float128_eq_quiet_rh850
+#define float128_le_quiet float128_le_quiet_rh850
+#define float128_lt_quiet float128_lt_quiet_rh850
+#define float128_unordered_quiet float128_unordered_quiet_rh850
+#define floatx80_compare floatx80_compare_rh850
+#define floatx80_compare_quiet floatx80_compare_quiet_rh850
+#define float128_compare float128_compare_rh850
+#define float128_compare_quiet float128_compare_quiet_rh850
+#define floatx80_scalbn floatx80_scalbn_rh850
+#define float128_scalbn float128_scalbn_rh850
+#define softfloat_init softfloat_init_rh850
+#define tcg_optimize tcg_optimize_rh850
+#define gen_new_label gen_new_label_rh850
+#define tcg_can_emit_vec_op tcg_can_emit_vec_op_rh850
+#define tcg_expand_vec_op tcg_expand_vec_op_rh850
+#define tcg_register_jit tcg_register_jit_rh850
+#define tcg_tb_insert tcg_tb_insert_rh850
+#define tcg_tb_remove tcg_tb_remove_rh850
+#define tcg_tb_lookup tcg_tb_lookup_rh850
+#define tcg_tb_foreach tcg_tb_foreach_rh850
+#define tcg_nb_tbs tcg_nb_tbs_rh850
+#define tcg_region_reset_all tcg_region_reset_all_rh850
+#define tcg_region_init tcg_region_init_rh850
+#define tcg_code_size tcg_code_size_rh850
+#define tcg_code_capacity tcg_code_capacity_rh850
+#define tcg_tb_phys_invalidate_count tcg_tb_phys_invalidate_count_rh850
+#define tcg_malloc_internal tcg_malloc_internal_rh850
+#define tcg_pool_reset tcg_pool_reset_rh850
+#define tcg_context_init tcg_context_init_rh850
+#define tcg_tb_alloc tcg_tb_alloc_rh850
+#define tcg_prologue_init tcg_prologue_init_rh850
+#define tcg_func_start tcg_func_start_rh850
+#define tcg_set_frame tcg_set_frame_rh850
+#define tcg_global_mem_new_internal tcg_global_mem_new_internal_rh850
+#define tcg_temp_new_internal tcg_temp_new_internal_rh850
+#define tcg_temp_new_vec tcg_temp_new_vec_rh850
+#define tcg_temp_new_vec_matching tcg_temp_new_vec_matching_rh850
+#define tcg_temp_free_internal tcg_temp_free_internal_rh850
+#define tcg_const_i32 tcg_const_i32_rh850
+#define tcg_const_i64 tcg_const_i64_rh850
+#define tcg_const_local_i32 tcg_const_local_i32_rh850
+#define tcg_const_local_i64 tcg_const_local_i64_rh850
+#define tcg_op_supported tcg_op_supported_rh850
+#define tcg_gen_callN tcg_gen_callN_rh850
+#define tcg_op_remove tcg_op_remove_rh850
+#define tcg_emit_op tcg_emit_op_rh850
+#define tcg_op_insert_before tcg_op_insert_before_rh850
+#define tcg_op_insert_after tcg_op_insert_after_rh850
+#define tcg_cpu_exec_time tcg_cpu_exec_time_rh850
+#define tcg_gen_code tcg_gen_code_rh850
+#define tcg_gen_op1 tcg_gen_op1_rh850
+#define tcg_gen_op2 tcg_gen_op2_rh850
+#define tcg_gen_op3 tcg_gen_op3_rh850
+#define tcg_gen_op4 tcg_gen_op4_rh850
+#define tcg_gen_op5 tcg_gen_op5_rh850
+#define tcg_gen_op6 tcg_gen_op6_rh850
+#define tcg_gen_mb tcg_gen_mb_rh850
+#define tcg_gen_addi_i32 tcg_gen_addi_i32_rh850
+#define tcg_gen_subfi_i32 tcg_gen_subfi_i32_rh850
+#define tcg_gen_subi_i32 tcg_gen_subi_i32_rh850
+#define tcg_gen_andi_i32 tcg_gen_andi_i32_rh850
+#define tcg_gen_ori_i32 tcg_gen_ori_i32_rh850
+#define tcg_gen_xori_i32 tcg_gen_xori_i32_rh850
+#define tcg_gen_shli_i32 tcg_gen_shli_i32_rh850
+#define tcg_gen_shri_i32 tcg_gen_shri_i32_rh850
+#define tcg_gen_sari_i32 tcg_gen_sari_i32_rh850
+#define tcg_gen_brcond_i32 tcg_gen_brcond_i32_rh850
+#define tcg_gen_brcondi_i32 tcg_gen_brcondi_i32_rh850
+#define tcg_gen_setcond_i32 tcg_gen_setcond_i32_rh850
+#define tcg_gen_setcondi_i32 tcg_gen_setcondi_i32_rh850
+#define tcg_gen_muli_i32 tcg_gen_muli_i32_rh850
+#define tcg_gen_div_i32 tcg_gen_div_i32_rh850
+#define tcg_gen_rem_i32 tcg_gen_rem_i32_rh850
+#define tcg_gen_divu_i32 tcg_gen_divu_i32_rh850
+#define tcg_gen_remu_i32 tcg_gen_remu_i32_rh850
+#define tcg_gen_andc_i32 tcg_gen_andc_i32_rh850
+#define tcg_gen_eqv_i32 tcg_gen_eqv_i32_rh850
+#define tcg_gen_nand_i32 tcg_gen_nand_i32_rh850
+#define tcg_gen_nor_i32 tcg_gen_nor_i32_rh850
+#define tcg_gen_orc_i32 tcg_gen_orc_i32_rh850
+#define tcg_gen_clz_i32 tcg_gen_clz_i32_rh850
+#define tcg_gen_clzi_i32 tcg_gen_clzi_i32_rh850
+#define tcg_gen_ctz_i32 tcg_gen_ctz_i32_rh850
+#define tcg_gen_ctzi_i32 tcg_gen_ctzi_i32_rh850
+#define tcg_gen_clrsb_i32 tcg_gen_clrsb_i32_rh850
+#define tcg_gen_ctpop_i32 tcg_gen_ctpop_i32_rh850
+#define tcg_gen_rotl_i32 tcg_gen_rotl_i32_rh850
+#define tcg_gen_rotli_i32 tcg_gen_rotli_i32_rh850
+#define tcg_gen_rotr_i32 tcg_gen_rotr_i32_rh850
+#define tcg_gen_rotri_i32 tcg_gen_rotri_i32_rh850
+#define tcg_gen_deposit_i32 tcg_gen_deposit_i32_rh850
+#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_rh850
+#define tcg_gen_extract_i32 tcg_gen_extract_i32_rh850
+#define tcg_gen_sextract_i32 tcg_gen_sextract_i32_rh850
+#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_rh850
+#define tcg_gen_movcond_i32 tcg_gen_movcond_i32_rh850
+#define tcg_gen_add2_i32 tcg_gen_add2_i32_rh850
+#define tcg_gen_sub2_i32 tcg_gen_sub2_i32_rh850
+#define tcg_gen_mulu2_i32 tcg_gen_mulu2_i32_rh850
+#define tcg_gen_muls2_i32 tcg_gen_muls2_i32_rh850
+#define tcg_gen_mulsu2_i32 tcg_gen_mulsu2_i32_rh850
+#define tcg_gen_ext8s_i32 tcg_gen_ext8s_i32_rh850
+#define tcg_gen_ext16s_i32 tcg_gen_ext16s_i32_rh850
+#define tcg_gen_ext8u_i32 tcg_gen_ext8u_i32_rh850
+#define tcg_gen_ext16u_i32 tcg_gen_ext16u_i32_rh850
+#define tcg_gen_bswap16_i32 tcg_gen_bswap16_i32_rh850
+#define tcg_gen_bswap32_i32 tcg_gen_bswap32_i32_rh850
+#define tcg_gen_smin_i32 tcg_gen_smin_i32_rh850
+#define tcg_gen_umin_i32 tcg_gen_umin_i32_rh850
+#define tcg_gen_smax_i32 tcg_gen_smax_i32_rh850
+#define tcg_gen_umax_i32 tcg_gen_umax_i32_rh850
+#define tcg_gen_abs_i32 tcg_gen_abs_i32_rh850
+#define tcg_gen_addi_i64 tcg_gen_addi_i64_rh850
+#define tcg_gen_subfi_i64 tcg_gen_subfi_i64_rh850
+#define tcg_gen_subi_i64 tcg_gen_subi_i64_rh850
+#define tcg_gen_andi_i64 tcg_gen_andi_i64_rh850
+#define tcg_gen_ori_i64 tcg_gen_ori_i64_rh850
+#define tcg_gen_xori_i64 tcg_gen_xori_i64_rh850
+#define tcg_gen_shli_i64 tcg_gen_shli_i64_rh850
+#define tcg_gen_shri_i64 tcg_gen_shri_i64_rh850
+#define tcg_gen_sari_i64 tcg_gen_sari_i64_rh850
+#define tcg_gen_brcond_i64 tcg_gen_brcond_i64_rh850
+#define tcg_gen_brcondi_i64 tcg_gen_brcondi_i64_rh850
+#define tcg_gen_setcond_i64 tcg_gen_setcond_i64_rh850
+#define tcg_gen_setcondi_i64 tcg_gen_setcondi_i64_rh850
+#define tcg_gen_muli_i64 tcg_gen_muli_i64_rh850
+#define tcg_gen_div_i64 tcg_gen_div_i64_rh850
+#define tcg_gen_rem_i64 tcg_gen_rem_i64_rh850
+#define tcg_gen_divu_i64 tcg_gen_divu_i64_rh850
+#define tcg_gen_remu_i64 tcg_gen_remu_i64_rh850
+#define tcg_gen_ext8s_i64 tcg_gen_ext8s_i64_rh850
+#define tcg_gen_ext16s_i64 tcg_gen_ext16s_i64_rh850
+#define tcg_gen_ext32s_i64 tcg_gen_ext32s_i64_rh850
+#define tcg_gen_ext8u_i64 tcg_gen_ext8u_i64_rh850
+#define tcg_gen_ext16u_i64 tcg_gen_ext16u_i64_rh850
+#define tcg_gen_ext32u_i64 tcg_gen_ext32u_i64_rh850
+#define tcg_gen_bswap16_i64 tcg_gen_bswap16_i64_rh850
+#define tcg_gen_bswap32_i64 tcg_gen_bswap32_i64_rh850
+#define tcg_gen_bswap64_i64 tcg_gen_bswap64_i64_rh850
+#define tcg_gen_not_i64 tcg_gen_not_i64_rh850
+#define tcg_gen_andc_i64 tcg_gen_andc_i64_rh850
+#define tcg_gen_eqv_i64 tcg_gen_eqv_i64_rh850
+#define tcg_gen_nand_i64 tcg_gen_nand_i64_rh850
+#define tcg_gen_nor_i64 tcg_gen_nor_i64_rh850
+#define tcg_gen_orc_i64 tcg_gen_orc_i64_rh850
+#define tcg_gen_clz_i64 tcg_gen_clz_i64_rh850
+#define tcg_gen_clzi_i64 tcg_gen_clzi_i64_rh850
+#define tcg_gen_ctz_i64 tcg_gen_ctz_i64_rh850
+#define tcg_gen_ctzi_i64 tcg_gen_ctzi_i64_rh850
+#define tcg_gen_clrsb_i64 tcg_gen_clrsb_i64_rh850
+#define tcg_gen_ctpop_i64 tcg_gen_ctpop_i64_rh850
+#define tcg_gen_rotl_i64 tcg_gen_rotl_i64_rh850
+#define tcg_gen_rotli_i64 tcg_gen_rotli_i64_rh850
+#define tcg_gen_rotr_i64 tcg_gen_rotr_i64_rh850
+#define tcg_gen_rotri_i64 tcg_gen_rotri_i64_rh850
+#define tcg_gen_deposit_i64 tcg_gen_deposit_i64_rh850
+#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_rh850
+#define tcg_gen_extract_i64 tcg_gen_extract_i64_rh850
+#define tcg_gen_sextract_i64 tcg_gen_sextract_i64_rh850
+#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_rh850
+#define tcg_gen_movcond_i64 tcg_gen_movcond_i64_rh850
+#define tcg_gen_add2_i64 tcg_gen_add2_i64_rh850
+#define tcg_gen_sub2_i64 tcg_gen_sub2_i64_rh850
+#define tcg_gen_mulu2_i64 tcg_gen_mulu2_i64_rh850
+#define tcg_gen_muls2_i64 tcg_gen_muls2_i64_rh850
+#define tcg_gen_mulsu2_i64 tcg_gen_mulsu2_i64_rh850
+#define tcg_gen_smin_i64 tcg_gen_smin_i64_rh850
+#define tcg_gen_umin_i64 tcg_gen_umin_i64_rh850
+#define tcg_gen_smax_i64 tcg_gen_smax_i64_rh850
+#define tcg_gen_umax_i64 tcg_gen_umax_i64_rh850
+#define tcg_gen_abs_i64 tcg_gen_abs_i64_rh850
+#define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_rh850
+#define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_rh850
+#define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_rh850
+#define tcg_gen_ext_i32_i64 tcg_gen_ext_i32_i64_rh850
+#define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_rh850
+#define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_rh850
+#define tcg_gen_extr32_i64 tcg_gen_extr32_i64_rh850
+#define tcg_gen_exit_tb tcg_gen_exit_tb_rh850
+#define tcg_gen_goto_tb tcg_gen_goto_tb_rh850
+#define tcg_gen_lookup_and_goto_ptr tcg_gen_lookup_and_goto_ptr_rh850
+#define check_exit_request check_exit_request_rh850
+#define tcg_gen_qemu_ld_i32 tcg_gen_qemu_ld_i32_rh850
+#define tcg_gen_qemu_st_i32 tcg_gen_qemu_st_i32_rh850
+#define tcg_gen_qemu_ld_i64 tcg_gen_qemu_ld_i64_rh850
+#define tcg_gen_qemu_st_i64 tcg_gen_qemu_st_i64_rh850
+#define tcg_gen_atomic_cmpxchg_i32 tcg_gen_atomic_cmpxchg_i32_rh850
+#define tcg_gen_atomic_cmpxchg_i64 tcg_gen_atomic_cmpxchg_i64_rh850
+#define tcg_gen_atomic_fetch_add_i32 tcg_gen_atomic_fetch_add_i32_rh850
+#define tcg_gen_atomic_fetch_add_i64 tcg_gen_atomic_fetch_add_i64_rh850
+#define tcg_gen_atomic_fetch_and_i32 tcg_gen_atomic_fetch_and_i32_rh850
+#define tcg_gen_atomic_fetch_and_i64 tcg_gen_atomic_fetch_and_i64_rh850
+#define tcg_gen_atomic_fetch_or_i32 tcg_gen_atomic_fetch_or_i32_rh850
+#define tcg_gen_atomic_fetch_or_i64 tcg_gen_atomic_fetch_or_i64_rh850
+#define tcg_gen_atomic_fetch_xor_i32 tcg_gen_atomic_fetch_xor_i32_rh850
+#define tcg_gen_atomic_fetch_xor_i64 tcg_gen_atomic_fetch_xor_i64_rh850
+#define tcg_gen_atomic_fetch_smin_i32 tcg_gen_atomic_fetch_smin_i32_rh850
+#define tcg_gen_atomic_fetch_smin_i64 tcg_gen_atomic_fetch_smin_i64_rh850
+#define tcg_gen_atomic_fetch_umin_i32 tcg_gen_atomic_fetch_umin_i32_rh850
+#define tcg_gen_atomic_fetch_umin_i64 tcg_gen_atomic_fetch_umin_i64_rh850
+#define tcg_gen_atomic_fetch_smax_i32 tcg_gen_atomic_fetch_smax_i32_rh850
+#define tcg_gen_atomic_fetch_smax_i64 tcg_gen_atomic_fetch_smax_i64_rh850
+#define tcg_gen_atomic_fetch_umax_i32 tcg_gen_atomic_fetch_umax_i32_rh850
+#define tcg_gen_atomic_fetch_umax_i64 tcg_gen_atomic_fetch_umax_i64_rh850
+#define tcg_gen_atomic_add_fetch_i32 tcg_gen_atomic_add_fetch_i32_rh850
+#define tcg_gen_atomic_add_fetch_i64 tcg_gen_atomic_add_fetch_i64_rh850
+#define tcg_gen_atomic_and_fetch_i32 tcg_gen_atomic_and_fetch_i32_rh850
+#define tcg_gen_atomic_and_fetch_i64 tcg_gen_atomic_and_fetch_i64_rh850
+#define tcg_gen_atomic_or_fetch_i32 tcg_gen_atomic_or_fetch_i32_rh850
+#define tcg_gen_atomic_or_fetch_i64 tcg_gen_atomic_or_fetch_i64_rh850
+#define tcg_gen_atomic_xor_fetch_i32 tcg_gen_atomic_xor_fetch_i32_rh850
+#define tcg_gen_atomic_xor_fetch_i64 tcg_gen_atomic_xor_fetch_i64_rh850
+#define tcg_gen_atomic_smin_fetch_i32 tcg_gen_atomic_smin_fetch_i32_rh850
+#define tcg_gen_atomic_smin_fetch_i64 tcg_gen_atomic_smin_fetch_i64_rh850
+#define tcg_gen_atomic_umin_fetch_i32 tcg_gen_atomic_umin_fetch_i32_rh850
+#define tcg_gen_atomic_umin_fetch_i64 tcg_gen_atomic_umin_fetch_i64_rh850
+#define tcg_gen_atomic_smax_fetch_i32 tcg_gen_atomic_smax_fetch_i32_rh850
+#define tcg_gen_atomic_smax_fetch_i64 tcg_gen_atomic_smax_fetch_i64_rh850
+#define tcg_gen_atomic_umax_fetch_i32 tcg_gen_atomic_umax_fetch_i32_rh850
+#define tcg_gen_atomic_umax_fetch_i64 tcg_gen_atomic_umax_fetch_i64_rh850
+#define tcg_gen_atomic_xchg_i32 tcg_gen_atomic_xchg_i32_rh850
+#define tcg_gen_atomic_xchg_i64 tcg_gen_atomic_xchg_i64_rh850
+#define simd_desc simd_desc_rh850
+#define tcg_gen_gvec_2_ool tcg_gen_gvec_2_ool_rh850
+#define tcg_gen_gvec_2i_ool tcg_gen_gvec_2i_ool_rh850
+#define tcg_gen_gvec_3_ool tcg_gen_gvec_3_ool_rh850
+#define tcg_gen_gvec_4_ool tcg_gen_gvec_4_ool_rh850
+#define tcg_gen_gvec_5_ool tcg_gen_gvec_5_ool_rh850
+#define tcg_gen_gvec_2_ptr tcg_gen_gvec_2_ptr_rh850
+#define tcg_gen_gvec_3_ptr tcg_gen_gvec_3_ptr_rh850
+#define tcg_gen_gvec_4_ptr tcg_gen_gvec_4_ptr_rh850
+#define tcg_gen_gvec_5_ptr tcg_gen_gvec_5_ptr_rh850
+#define tcg_gen_gvec_2 tcg_gen_gvec_2_rh850
+#define tcg_gen_gvec_2i tcg_gen_gvec_2i_rh850
+#define tcg_gen_gvec_2s tcg_gen_gvec_2s_rh850
+#define tcg_gen_gvec_3 tcg_gen_gvec_3_rh850
+#define tcg_gen_gvec_3i tcg_gen_gvec_3i_rh850
+#define tcg_gen_gvec_4 tcg_gen_gvec_4_rh850
+#define tcg_gen_gvec_mov tcg_gen_gvec_mov_rh850
+#define tcg_gen_gvec_dup_i32 tcg_gen_gvec_dup_i32_rh850
+#define tcg_gen_gvec_dup_i64 tcg_gen_gvec_dup_i64_rh850
+#define tcg_gen_gvec_dup_mem tcg_gen_gvec_dup_mem_rh850
+#define tcg_gen_gvec_dup64i tcg_gen_gvec_dup64i_rh850
+#define tcg_gen_gvec_dup32i tcg_gen_gvec_dup32i_rh850
+#define tcg_gen_gvec_dup16i tcg_gen_gvec_dup16i_rh850
+#define tcg_gen_gvec_dup8i tcg_gen_gvec_dup8i_rh850
+#define tcg_gen_gvec_not tcg_gen_gvec_not_rh850
+#define tcg_gen_vec_add8_i64 tcg_gen_vec_add8_i64_rh850
+#define tcg_gen_vec_add16_i64 tcg_gen_vec_add16_i64_rh850
+#define tcg_gen_vec_add32_i64 tcg_gen_vec_add32_i64_rh850
+#define tcg_gen_gvec_add tcg_gen_gvec_add_rh850
+#define tcg_gen_gvec_adds tcg_gen_gvec_adds_rh850
+#define tcg_gen_gvec_addi tcg_gen_gvec_addi_rh850
+#define tcg_gen_gvec_subs tcg_gen_gvec_subs_rh850
+#define tcg_gen_vec_sub8_i64 tcg_gen_vec_sub8_i64_rh850
+#define tcg_gen_vec_sub16_i64 tcg_gen_vec_sub16_i64_rh850
+#define tcg_gen_vec_sub32_i64 tcg_gen_vec_sub32_i64_rh850
+#define tcg_gen_gvec_sub tcg_gen_gvec_sub_rh850
+#define tcg_gen_gvec_mul tcg_gen_gvec_mul_rh850
+#define tcg_gen_gvec_muls tcg_gen_gvec_muls_rh850
+#define tcg_gen_gvec_muli tcg_gen_gvec_muli_rh850
+#define tcg_gen_gvec_ssadd tcg_gen_gvec_ssadd_rh850
+#define tcg_gen_gvec_sssub tcg_gen_gvec_sssub_rh850
+#define tcg_gen_gvec_usadd tcg_gen_gvec_usadd_rh850
+#define tcg_gen_gvec_ussub tcg_gen_gvec_ussub_rh850
+#define tcg_gen_gvec_smin tcg_gen_gvec_smin_rh850
+#define tcg_gen_gvec_umin tcg_gen_gvec_umin_rh850
+#define tcg_gen_gvec_smax tcg_gen_gvec_smax_rh850
+#define tcg_gen_gvec_umax tcg_gen_gvec_umax_rh850
+#define tcg_gen_vec_neg8_i64 tcg_gen_vec_neg8_i64_rh850
+#define tcg_gen_vec_neg16_i64 tcg_gen_vec_neg16_i64_rh850
+#define tcg_gen_vec_neg32_i64 tcg_gen_vec_neg32_i64_rh850
+#define tcg_gen_gvec_neg tcg_gen_gvec_neg_rh850
+#define tcg_gen_gvec_abs tcg_gen_gvec_abs_rh850
+#define tcg_gen_gvec_and tcg_gen_gvec_and_rh850
+#define tcg_gen_gvec_or tcg_gen_gvec_or_rh850
+#define tcg_gen_gvec_xor tcg_gen_gvec_xor_rh850
+#define tcg_gen_gvec_andc tcg_gen_gvec_andc_rh850
+#define tcg_gen_gvec_orc tcg_gen_gvec_orc_rh850
+#define tcg_gen_gvec_nand tcg_gen_gvec_nand_rh850
+#define tcg_gen_gvec_nor tcg_gen_gvec_nor_rh850
+#define tcg_gen_gvec_eqv tcg_gen_gvec_eqv_rh850
+#define tcg_gen_gvec_ands tcg_gen_gvec_ands_rh850
+#define tcg_gen_gvec_andi tcg_gen_gvec_andi_rh850
+#define tcg_gen_gvec_xors tcg_gen_gvec_xors_rh850
+#define tcg_gen_gvec_xori tcg_gen_gvec_xori_rh850
+#define tcg_gen_gvec_ors tcg_gen_gvec_ors_rh850
+#define tcg_gen_gvec_ori tcg_gen_gvec_ori_rh850
+#define tcg_gen_vec_shl8i_i64 tcg_gen_vec_shl8i_i64_rh850
+#define tcg_gen_vec_shl16i_i64 tcg_gen_vec_shl16i_i64_rh850
+#define tcg_gen_gvec_shli tcg_gen_gvec_shli_rh850
+#define tcg_gen_vec_shr8i_i64 tcg_gen_vec_shr8i_i64_rh850
+#define tcg_gen_vec_shr16i_i64 tcg_gen_vec_shr16i_i64_rh850
+#define tcg_gen_gvec_shri tcg_gen_gvec_shri_rh850
+#define tcg_gen_vec_sar8i_i64 tcg_gen_vec_sar8i_i64_rh850
+#define tcg_gen_vec_sar16i_i64 tcg_gen_vec_sar16i_i64_rh850
+#define tcg_gen_gvec_sari tcg_gen_gvec_sari_rh850
+#define tcg_gen_gvec_shls tcg_gen_gvec_shls_rh850
+#define tcg_gen_gvec_shrs tcg_gen_gvec_shrs_rh850
+#define tcg_gen_gvec_sars tcg_gen_gvec_sars_rh850
+#define tcg_gen_gvec_shlv tcg_gen_gvec_shlv_rh850
+#define tcg_gen_gvec_shrv tcg_gen_gvec_shrv_rh850
+#define tcg_gen_gvec_sarv tcg_gen_gvec_sarv_rh850
+#define tcg_gen_gvec_cmp tcg_gen_gvec_cmp_rh850
+#define tcg_gen_gvec_bitsel tcg_gen_gvec_bitsel_rh850
+#define tcg_can_emit_vecop_list tcg_can_emit_vecop_list_rh850
+#define vec_gen_2 vec_gen_2_rh850
+#define vec_gen_3 vec_gen_3_rh850
+#define vec_gen_4 vec_gen_4_rh850
+#define tcg_gen_mov_vec tcg_gen_mov_vec_rh850
+#define tcg_const_zeros_vec tcg_const_zeros_vec_rh850
+#define tcg_const_ones_vec tcg_const_ones_vec_rh850
+#define tcg_const_zeros_vec_matching tcg_const_zeros_vec_matching_rh850
+#define tcg_const_ones_vec_matching tcg_const_ones_vec_matching_rh850
+#define tcg_gen_dup64i_vec tcg_gen_dup64i_vec_rh850
+#define tcg_gen_dup32i_vec tcg_gen_dup32i_vec_rh850
+#define tcg_gen_dup16i_vec tcg_gen_dup16i_vec_rh850
+#define tcg_gen_dup8i_vec tcg_gen_dup8i_vec_rh850
+#define tcg_gen_dupi_vec tcg_gen_dupi_vec_rh850
+#define tcg_gen_dup_i64_vec tcg_gen_dup_i64_vec_rh850
+#define tcg_gen_dup_i32_vec tcg_gen_dup_i32_vec_rh850
+#define tcg_gen_dup_mem_vec tcg_gen_dup_mem_vec_rh850
+#define tcg_gen_ld_vec tcg_gen_ld_vec_rh850
+#define tcg_gen_st_vec tcg_gen_st_vec_rh850
+#define tcg_gen_stl_vec tcg_gen_stl_vec_rh850
+#define tcg_gen_and_vec tcg_gen_and_vec_rh850
+#define tcg_gen_or_vec tcg_gen_or_vec_rh850
+#define tcg_gen_xor_vec tcg_gen_xor_vec_rh850
+#define tcg_gen_andc_vec tcg_gen_andc_vec_rh850
+#define tcg_gen_orc_vec tcg_gen_orc_vec_rh850
+#define tcg_gen_nand_vec tcg_gen_nand_vec_rh850
+#define tcg_gen_nor_vec tcg_gen_nor_vec_rh850
+#define tcg_gen_eqv_vec tcg_gen_eqv_vec_rh850
+#define tcg_gen_not_vec tcg_gen_not_vec_rh850
+#define tcg_gen_neg_vec tcg_gen_neg_vec_rh850
+#define tcg_gen_abs_vec tcg_gen_abs_vec_rh850
+#define tcg_gen_shli_vec tcg_gen_shli_vec_rh850
+#define tcg_gen_shri_vec tcg_gen_shri_vec_rh850
+#define tcg_gen_sari_vec tcg_gen_sari_vec_rh850
+#define tcg_gen_cmp_vec tcg_gen_cmp_vec_rh850
+#define tcg_gen_add_vec tcg_gen_add_vec_rh850
+#define tcg_gen_sub_vec tcg_gen_sub_vec_rh850
+#define tcg_gen_mul_vec tcg_gen_mul_vec_rh850
+#define tcg_gen_ssadd_vec tcg_gen_ssadd_vec_rh850
+#define tcg_gen_usadd_vec tcg_gen_usadd_vec_rh850
+#define tcg_gen_sssub_vec tcg_gen_sssub_vec_rh850
+#define tcg_gen_ussub_vec tcg_gen_ussub_vec_rh850
+#define tcg_gen_smin_vec tcg_gen_smin_vec_rh850
+#define tcg_gen_umin_vec tcg_gen_umin_vec_rh850
+#define tcg_gen_smax_vec tcg_gen_smax_vec_rh850
+#define tcg_gen_umax_vec tcg_gen_umax_vec_rh850
+#define tcg_gen_shlv_vec tcg_gen_shlv_vec_rh850
+#define tcg_gen_shrv_vec tcg_gen_shrv_vec_rh850
+#define tcg_gen_sarv_vec tcg_gen_sarv_vec_rh850
+#define tcg_gen_shls_vec tcg_gen_shls_vec_rh850
+#define tcg_gen_shrs_vec tcg_gen_shrs_vec_rh850
+#define tcg_gen_sars_vec tcg_gen_sars_vec_rh850
+#define tcg_gen_bitsel_vec tcg_gen_bitsel_vec_rh850
+#define tcg_gen_cmpsel_vec tcg_gen_cmpsel_vec_rh850
+#define tb_htable_lookup tb_htable_lookup_rh850
+#define tb_set_jmp_target tb_set_jmp_target_rh850
+#define cpu_exec cpu_exec_rh850
+#define cpu_loop_exit_noexc cpu_loop_exit_noexc_rh850
+#define cpu_reloading_memory_map cpu_reloading_memory_map_rh850
+#define cpu_loop_exit cpu_loop_exit_rh850
+#define cpu_loop_exit_restore cpu_loop_exit_restore_rh850
+#define cpu_loop_exit_atomic cpu_loop_exit_atomic_rh850
+#define tlb_init tlb_init_rh850
+#define tlb_flush_by_mmuidx tlb_flush_by_mmuidx_rh850
+#define tlb_flush tlb_flush_rh850
+#define tlb_flush_by_mmuidx_all_cpus tlb_flush_by_mmuidx_all_cpus_rh850
+#define tlb_flush_all_cpus tlb_flush_all_cpus_rh850
+#define tlb_flush_by_mmuidx_all_cpus_synced tlb_flush_by_mmuidx_all_cpus_synced_rh850
+#define tlb_flush_all_cpus_synced tlb_flush_all_cpus_synced_rh850
+#define tlb_flush_page_by_mmuidx tlb_flush_page_by_mmuidx_rh850
+#define tlb_flush_page tlb_flush_page_rh850
+#define tlb_flush_page_by_mmuidx_all_cpus tlb_flush_page_by_mmuidx_all_cpus_rh850
+#define tlb_flush_page_all_cpus tlb_flush_page_all_cpus_rh850
+#define tlb_flush_page_by_mmuidx_all_cpus_synced tlb_flush_page_by_mmuidx_all_cpus_synced_rh850
+#define tlb_flush_page_all_cpus_synced tlb_flush_page_all_cpus_synced_rh850
+#define tlb_protect_code tlb_protect_code_rh850
+#define tlb_unprotect_code tlb_unprotect_code_rh850
+#define tlb_reset_dirty tlb_reset_dirty_rh850
+#define tlb_set_dirty tlb_set_dirty_rh850
+#define tlb_set_page_with_attrs tlb_set_page_with_attrs_rh850
+#define tlb_set_page tlb_set_page_rh850
+#define get_page_addr_code_hostp get_page_addr_code_hostp_rh850
+#define get_page_addr_code get_page_addr_code_rh850
+#define probe_access probe_access_rh850
+#define tlb_vaddr_to_host tlb_vaddr_to_host_rh850
+#define helper_ret_ldub_mmu helper_ret_ldub_mmu_rh850
+#define helper_le_lduw_mmu helper_le_lduw_mmu_rh850
+#define helper_be_lduw_mmu helper_be_lduw_mmu_rh850
+#define helper_le_ldul_mmu helper_le_ldul_mmu_rh850
+#define helper_be_ldul_mmu helper_be_ldul_mmu_rh850
+#define helper_le_ldq_mmu helper_le_ldq_mmu_rh850
+#define helper_be_ldq_mmu helper_be_ldq_mmu_rh850
+#define helper_ret_ldsb_mmu helper_ret_ldsb_mmu_rh850
+#define helper_le_ldsw_mmu helper_le_ldsw_mmu_rh850
+#define helper_be_ldsw_mmu helper_be_ldsw_mmu_rh850
+#define helper_le_ldsl_mmu helper_le_ldsl_mmu_rh850
+#define helper_be_ldsl_mmu helper_be_ldsl_mmu_rh850
+#define cpu_ldub_mmuidx_ra cpu_ldub_mmuidx_ra_rh850
+#define cpu_ldsb_mmuidx_ra cpu_ldsb_mmuidx_ra_rh850
+#define cpu_lduw_mmuidx_ra cpu_lduw_mmuidx_ra_rh850
+#define cpu_ldsw_mmuidx_ra cpu_ldsw_mmuidx_ra_rh850
+#define cpu_ldl_mmuidx_ra cpu_ldl_mmuidx_ra_rh850
+#define cpu_ldq_mmuidx_ra cpu_ldq_mmuidx_ra_rh850
+#define cpu_ldub_data_ra cpu_ldub_data_ra_rh850
+#define cpu_ldsb_data_ra cpu_ldsb_data_ra_rh850
+#define cpu_lduw_data_ra cpu_lduw_data_ra_rh850
+#define cpu_ldsw_data_ra cpu_ldsw_data_ra_rh850
+#define cpu_ldl_data_ra cpu_ldl_data_ra_rh850
+#define cpu_ldq_data_ra cpu_ldq_data_ra_rh850
+#define cpu_ldub_data cpu_ldub_data_rh850
+#define cpu_ldsb_data cpu_ldsb_data_rh850
+#define cpu_lduw_data cpu_lduw_data_rh850
+#define cpu_ldsw_data cpu_ldsw_data_rh850
+#define cpu_ldl_data cpu_ldl_data_rh850
+#define cpu_ldq_data cpu_ldq_data_rh850
+#define helper_ret_stb_mmu helper_ret_stb_mmu_rh850
+#define helper_le_stw_mmu helper_le_stw_mmu_rh850
+#define helper_be_stw_mmu helper_be_stw_mmu_rh850
+#define helper_le_stl_mmu helper_le_stl_mmu_rh850
+#define helper_be_stl_mmu helper_be_stl_mmu_rh850
+#define helper_le_stq_mmu helper_le_stq_mmu_rh850
+#define helper_be_stq_mmu helper_be_stq_mmu_rh850
+#define cpu_stb_mmuidx_ra cpu_stb_mmuidx_ra_rh850
+#define cpu_stw_mmuidx_ra cpu_stw_mmuidx_ra_rh850
+#define cpu_stl_mmuidx_ra cpu_stl_mmuidx_ra_rh850
+#define cpu_stq_mmuidx_ra cpu_stq_mmuidx_ra_rh850
+#define cpu_stb_data_ra cpu_stb_data_ra_rh850
+#define cpu_stw_data_ra cpu_stw_data_ra_rh850
+#define cpu_stl_data_ra cpu_stl_data_ra_rh850
+#define cpu_stq_data_ra cpu_stq_data_ra_rh850
+#define cpu_stb_data cpu_stb_data_rh850
+#define cpu_stw_data cpu_stw_data_rh850
+#define cpu_stl_data cpu_stl_data_rh850
+#define cpu_stq_data cpu_stq_data_rh850
+#define helper_atomic_cmpxchgb_mmu helper_atomic_cmpxchgb_mmu_rh850
+#define helper_atomic_xchgb_mmu helper_atomic_xchgb_mmu_rh850
+#define helper_atomic_fetch_addb_mmu helper_atomic_fetch_addb_mmu_rh850
+#define helper_atomic_fetch_andb_mmu helper_atomic_fetch_andb_mmu_rh850
+#define helper_atomic_fetch_orb_mmu helper_atomic_fetch_orb_mmu_rh850
+#define helper_atomic_fetch_xorb_mmu helper_atomic_fetch_xorb_mmu_rh850
+#define helper_atomic_add_fetchb_mmu helper_atomic_add_fetchb_mmu_rh850
+#define helper_atomic_and_fetchb_mmu helper_atomic_and_fetchb_mmu_rh850
+#define helper_atomic_or_fetchb_mmu helper_atomic_or_fetchb_mmu_rh850
+#define helper_atomic_xor_fetchb_mmu helper_atomic_xor_fetchb_mmu_rh850
+#define helper_atomic_fetch_sminb_mmu helper_atomic_fetch_sminb_mmu_rh850
+#define helper_atomic_fetch_uminb_mmu helper_atomic_fetch_uminb_mmu_rh850
+#define helper_atomic_fetch_smaxb_mmu helper_atomic_fetch_smaxb_mmu_rh850
+#define helper_atomic_fetch_umaxb_mmu helper_atomic_fetch_umaxb_mmu_rh850
+#define helper_atomic_smin_fetchb_mmu helper_atomic_smin_fetchb_mmu_rh850
+#define helper_atomic_umin_fetchb_mmu helper_atomic_umin_fetchb_mmu_rh850
+#define helper_atomic_smax_fetchb_mmu helper_atomic_smax_fetchb_mmu_rh850
+#define helper_atomic_umax_fetchb_mmu helper_atomic_umax_fetchb_mmu_rh850
+#define helper_atomic_cmpxchgw_le_mmu helper_atomic_cmpxchgw_le_mmu_rh850
+#define helper_atomic_xchgw_le_mmu helper_atomic_xchgw_le_mmu_rh850
+#define helper_atomic_fetch_addw_le_mmu helper_atomic_fetch_addw_le_mmu_rh850
+#define helper_atomic_fetch_andw_le_mmu helper_atomic_fetch_andw_le_mmu_rh850
+#define helper_atomic_fetch_orw_le_mmu helper_atomic_fetch_orw_le_mmu_rh850
+#define helper_atomic_fetch_xorw_le_mmu helper_atomic_fetch_xorw_le_mmu_rh850
+#define helper_atomic_add_fetchw_le_mmu helper_atomic_add_fetchw_le_mmu_rh850
+#define helper_atomic_and_fetchw_le_mmu helper_atomic_and_fetchw_le_mmu_rh850
+#define helper_atomic_or_fetchw_le_mmu helper_atomic_or_fetchw_le_mmu_rh850
+#define helper_atomic_xor_fetchw_le_mmu helper_atomic_xor_fetchw_le_mmu_rh850
+#define helper_atomic_fetch_sminw_le_mmu helper_atomic_fetch_sminw_le_mmu_rh850
+#define helper_atomic_fetch_uminw_le_mmu helper_atomic_fetch_uminw_le_mmu_rh850
+#define helper_atomic_fetch_smaxw_le_mmu helper_atomic_fetch_smaxw_le_mmu_rh850
+#define helper_atomic_fetch_umaxw_le_mmu helper_atomic_fetch_umaxw_le_mmu_rh850
+#define helper_atomic_smin_fetchw_le_mmu helper_atomic_smin_fetchw_le_mmu_rh850
+#define helper_atomic_umin_fetchw_le_mmu helper_atomic_umin_fetchw_le_mmu_rh850
+#define helper_atomic_smax_fetchw_le_mmu helper_atomic_smax_fetchw_le_mmu_rh850
+#define helper_atomic_umax_fetchw_le_mmu helper_atomic_umax_fetchw_le_mmu_rh850
+#define helper_atomic_cmpxchgw_be_mmu helper_atomic_cmpxchgw_be_mmu_rh850
+#define helper_atomic_xchgw_be_mmu helper_atomic_xchgw_be_mmu_rh850
+#define helper_atomic_fetch_andw_be_mmu helper_atomic_fetch_andw_be_mmu_rh850
+#define helper_atomic_fetch_orw_be_mmu helper_atomic_fetch_orw_be_mmu_rh850
+#define helper_atomic_fetch_xorw_be_mmu helper_atomic_fetch_xorw_be_mmu_rh850
+#define helper_atomic_and_fetchw_be_mmu helper_atomic_and_fetchw_be_mmu_rh850
+#define helper_atomic_or_fetchw_be_mmu helper_atomic_or_fetchw_be_mmu_rh850
+#define helper_atomic_xor_fetchw_be_mmu helper_atomic_xor_fetchw_be_mmu_rh850
+#define helper_atomic_fetch_sminw_be_mmu helper_atomic_fetch_sminw_be_mmu_rh850
+#define helper_atomic_fetch_uminw_be_mmu helper_atomic_fetch_uminw_be_mmu_rh850
+#define helper_atomic_fetch_smaxw_be_mmu helper_atomic_fetch_smaxw_be_mmu_rh850
+#define helper_atomic_fetch_umaxw_be_mmu helper_atomic_fetch_umaxw_be_mmu_rh850
+#define helper_atomic_smin_fetchw_be_mmu helper_atomic_smin_fetchw_be_mmu_rh850
+#define helper_atomic_umin_fetchw_be_mmu helper_atomic_umin_fetchw_be_mmu_rh850
+#define helper_atomic_smax_fetchw_be_mmu helper_atomic_smax_fetchw_be_mmu_rh850
+#define helper_atomic_umax_fetchw_be_mmu helper_atomic_umax_fetchw_be_mmu_rh850
+#define helper_atomic_fetch_addw_be_mmu helper_atomic_fetch_addw_be_mmu_rh850
+#define helper_atomic_add_fetchw_be_mmu helper_atomic_add_fetchw_be_mmu_rh850
+#define helper_atomic_cmpxchgl_le_mmu helper_atomic_cmpxchgl_le_mmu_rh850
+#define helper_atomic_xchgl_le_mmu helper_atomic_xchgl_le_mmu_rh850
+#define helper_atomic_fetch_addl_le_mmu helper_atomic_fetch_addl_le_mmu_rh850
+#define helper_atomic_fetch_andl_le_mmu helper_atomic_fetch_andl_le_mmu_rh850
+#define helper_atomic_fetch_orl_le_mmu helper_atomic_fetch_orl_le_mmu_rh850
+#define helper_atomic_fetch_xorl_le_mmu helper_atomic_fetch_xorl_le_mmu_rh850
+#define helper_atomic_add_fetchl_le_mmu helper_atomic_add_fetchl_le_mmu_rh850
+#define helper_atomic_and_fetchl_le_mmu helper_atomic_and_fetchl_le_mmu_rh850
+#define helper_atomic_or_fetchl_le_mmu helper_atomic_or_fetchl_le_mmu_rh850
+#define helper_atomic_xor_fetchl_le_mmu helper_atomic_xor_fetchl_le_mmu_rh850
+#define helper_atomic_fetch_sminl_le_mmu helper_atomic_fetch_sminl_le_mmu_rh850
+#define helper_atomic_fetch_uminl_le_mmu helper_atomic_fetch_uminl_le_mmu_rh850
+#define helper_atomic_fetch_smaxl_le_mmu helper_atomic_fetch_smaxl_le_mmu_rh850
+#define helper_atomic_fetch_umaxl_le_mmu helper_atomic_fetch_umaxl_le_mmu_rh850
+#define helper_atomic_smin_fetchl_le_mmu helper_atomic_smin_fetchl_le_mmu_rh850
+#define helper_atomic_umin_fetchl_le_mmu helper_atomic_umin_fetchl_le_mmu_rh850
+#define helper_atomic_smax_fetchl_le_mmu helper_atomic_smax_fetchl_le_mmu_rh850
+#define helper_atomic_umax_fetchl_le_mmu helper_atomic_umax_fetchl_le_mmu_rh850
+#define helper_atomic_cmpxchgl_be_mmu helper_atomic_cmpxchgl_be_mmu_rh850
+#define helper_atomic_xchgl_be_mmu helper_atomic_xchgl_be_mmu_rh850
+#define helper_atomic_fetch_andl_be_mmu helper_atomic_fetch_andl_be_mmu_rh850
+#define helper_atomic_fetch_orl_be_mmu helper_atomic_fetch_orl_be_mmu_rh850
+#define helper_atomic_fetch_xorl_be_mmu helper_atomic_fetch_xorl_be_mmu_rh850
+#define helper_atomic_and_fetchl_be_mmu helper_atomic_and_fetchl_be_mmu_rh850
+#define helper_atomic_or_fetchl_be_mmu helper_atomic_or_fetchl_be_mmu_rh850
+#define helper_atomic_xor_fetchl_be_mmu helper_atomic_xor_fetchl_be_mmu_rh850
+#define helper_atomic_fetch_sminl_be_mmu helper_atomic_fetch_sminl_be_mmu_rh850
+#define helper_atomic_fetch_uminl_be_mmu helper_atomic_fetch_uminl_be_mmu_rh850
+#define helper_atomic_fetch_smaxl_be_mmu helper_atomic_fetch_smaxl_be_mmu_rh850
+#define helper_atomic_fetch_umaxl_be_mmu helper_atomic_fetch_umaxl_be_mmu_rh850
+#define helper_atomic_smin_fetchl_be_mmu helper_atomic_smin_fetchl_be_mmu_rh850
+#define helper_atomic_umin_fetchl_be_mmu helper_atomic_umin_fetchl_be_mmu_rh850
+#define helper_atomic_smax_fetchl_be_mmu helper_atomic_smax_fetchl_be_mmu_rh850
+#define helper_atomic_umax_fetchl_be_mmu helper_atomic_umax_fetchl_be_mmu_rh850
+#define helper_atomic_fetch_addl_be_mmu helper_atomic_fetch_addl_be_mmu_rh850
+#define helper_atomic_add_fetchl_be_mmu helper_atomic_add_fetchl_be_mmu_rh850
+#define helper_atomic_cmpxchgq_le_mmu helper_atomic_cmpxchgq_le_mmu_rh850
+#define helper_atomic_xchgq_le_mmu helper_atomic_xchgq_le_mmu_rh850
+#define helper_atomic_fetch_addq_le_mmu helper_atomic_fetch_addq_le_mmu_rh850
+#define helper_atomic_fetch_andq_le_mmu helper_atomic_fetch_andq_le_mmu_rh850
+#define helper_atomic_fetch_orq_le_mmu helper_atomic_fetch_orq_le_mmu_rh850
+#define helper_atomic_fetch_xorq_le_mmu helper_atomic_fetch_xorq_le_mmu_rh850
+#define helper_atomic_add_fetchq_le_mmu helper_atomic_add_fetchq_le_mmu_rh850
+#define helper_atomic_and_fetchq_le_mmu helper_atomic_and_fetchq_le_mmu_rh850
+#define helper_atomic_or_fetchq_le_mmu helper_atomic_or_fetchq_le_mmu_rh850
+#define helper_atomic_xor_fetchq_le_mmu helper_atomic_xor_fetchq_le_mmu_rh850
+#define helper_atomic_fetch_sminq_le_mmu helper_atomic_fetch_sminq_le_mmu_rh850
+#define helper_atomic_fetch_uminq_le_mmu helper_atomic_fetch_uminq_le_mmu_rh850
+#define helper_atomic_fetch_smaxq_le_mmu helper_atomic_fetch_smaxq_le_mmu_rh850
+#define helper_atomic_fetch_umaxq_le_mmu helper_atomic_fetch_umaxq_le_mmu_rh850
+#define helper_atomic_smin_fetchq_le_mmu helper_atomic_smin_fetchq_le_mmu_rh850
+#define helper_atomic_umin_fetchq_le_mmu helper_atomic_umin_fetchq_le_mmu_rh850
+#define helper_atomic_smax_fetchq_le_mmu helper_atomic_smax_fetchq_le_mmu_rh850
+#define helper_atomic_umax_fetchq_le_mmu helper_atomic_umax_fetchq_le_mmu_rh850
+#define helper_atomic_cmpxchgq_be_mmu helper_atomic_cmpxchgq_be_mmu_rh850
+#define helper_atomic_xchgq_be_mmu helper_atomic_xchgq_be_mmu_rh850
+#define helper_atomic_fetch_andq_be_mmu helper_atomic_fetch_andq_be_mmu_rh850
+#define helper_atomic_fetch_orq_be_mmu helper_atomic_fetch_orq_be_mmu_rh850
+#define helper_atomic_fetch_xorq_be_mmu helper_atomic_fetch_xorq_be_mmu_rh850
+#define helper_atomic_and_fetchq_be_mmu helper_atomic_and_fetchq_be_mmu_rh850
+#define helper_atomic_or_fetchq_be_mmu helper_atomic_or_fetchq_be_mmu_rh850
+#define helper_atomic_xor_fetchq_be_mmu helper_atomic_xor_fetchq_be_mmu_rh850
+#define helper_atomic_fetch_sminq_be_mmu helper_atomic_fetch_sminq_be_mmu_rh850
+#define helper_atomic_fetch_uminq_be_mmu helper_atomic_fetch_uminq_be_mmu_rh850
+#define helper_atomic_fetch_smaxq_be_mmu helper_atomic_fetch_smaxq_be_mmu_rh850
+#define helper_atomic_fetch_umaxq_be_mmu helper_atomic_fetch_umaxq_be_mmu_rh850
+#define helper_atomic_smin_fetchq_be_mmu helper_atomic_smin_fetchq_be_mmu_rh850
+#define helper_atomic_umin_fetchq_be_mmu helper_atomic_umin_fetchq_be_mmu_rh850
+#define helper_atomic_smax_fetchq_be_mmu helper_atomic_smax_fetchq_be_mmu_rh850
+#define helper_atomic_umax_fetchq_be_mmu helper_atomic_umax_fetchq_be_mmu_rh850
+#define helper_atomic_fetch_addq_be_mmu helper_atomic_fetch_addq_be_mmu_rh850
+#define helper_atomic_add_fetchq_be_mmu helper_atomic_add_fetchq_be_mmu_rh850
+#define helper_atomic_cmpxchgb helper_atomic_cmpxchgb_rh850
+#define helper_atomic_xchgb helper_atomic_xchgb_rh850
+#define helper_atomic_fetch_addb helper_atomic_fetch_addb_rh850
+#define helper_atomic_fetch_andb helper_atomic_fetch_andb_rh850
+#define helper_atomic_fetch_orb helper_atomic_fetch_orb_rh850
+#define helper_atomic_fetch_xorb helper_atomic_fetch_xorb_rh850
+#define helper_atomic_add_fetchb helper_atomic_add_fetchb_rh850
+#define helper_atomic_and_fetchb helper_atomic_and_fetchb_rh850
+#define helper_atomic_or_fetchb helper_atomic_or_fetchb_rh850
+#define helper_atomic_xor_fetchb helper_atomic_xor_fetchb_rh850
+#define helper_atomic_fetch_sminb helper_atomic_fetch_sminb_rh850
+#define helper_atomic_fetch_uminb helper_atomic_fetch_uminb_rh850
+#define helper_atomic_fetch_smaxb helper_atomic_fetch_smaxb_rh850
+#define helper_atomic_fetch_umaxb helper_atomic_fetch_umaxb_rh850
+#define helper_atomic_smin_fetchb helper_atomic_smin_fetchb_rh850
+#define helper_atomic_umin_fetchb helper_atomic_umin_fetchb_rh850
+#define helper_atomic_smax_fetchb helper_atomic_smax_fetchb_rh850
+#define helper_atomic_umax_fetchb helper_atomic_umax_fetchb_rh850
+#define helper_atomic_cmpxchgw_le helper_atomic_cmpxchgw_le_rh850
+#define helper_atomic_xchgw_le helper_atomic_xchgw_le_rh850
+#define helper_atomic_fetch_addw_le helper_atomic_fetch_addw_le_rh850
+#define helper_atomic_fetch_andw_le helper_atomic_fetch_andw_le_rh850
+#define helper_atomic_fetch_orw_le helper_atomic_fetch_orw_le_rh850
+#define helper_atomic_fetch_xorw_le helper_atomic_fetch_xorw_le_rh850
+#define helper_atomic_add_fetchw_le helper_atomic_add_fetchw_le_rh850
+#define helper_atomic_and_fetchw_le helper_atomic_and_fetchw_le_rh850
+#define helper_atomic_or_fetchw_le helper_atomic_or_fetchw_le_rh850
+#define helper_atomic_xor_fetchw_le helper_atomic_xor_fetchw_le_rh850
+#define helper_atomic_fetch_sminw_le helper_atomic_fetch_sminw_le_rh850
+#define helper_atomic_fetch_uminw_le helper_atomic_fetch_uminw_le_rh850
+#define helper_atomic_fetch_smaxw_le helper_atomic_fetch_smaxw_le_rh850
+#define helper_atomic_fetch_umaxw_le helper_atomic_fetch_umaxw_le_rh850
+#define helper_atomic_smin_fetchw_le helper_atomic_smin_fetchw_le_rh850
+#define helper_atomic_umin_fetchw_le helper_atomic_umin_fetchw_le_rh850
+#define helper_atomic_smax_fetchw_le helper_atomic_smax_fetchw_le_rh850
+#define helper_atomic_umax_fetchw_le helper_atomic_umax_fetchw_le_rh850
+#define helper_atomic_cmpxchgw_be helper_atomic_cmpxchgw_be_rh850
+#define helper_atomic_xchgw_be helper_atomic_xchgw_be_rh850
+#define helper_atomic_fetch_andw_be helper_atomic_fetch_andw_be_rh850
+#define helper_atomic_fetch_orw_be helper_atomic_fetch_orw_be_rh850
+#define helper_atomic_fetch_xorw_be helper_atomic_fetch_xorw_be_rh850
+#define helper_atomic_and_fetchw_be helper_atomic_and_fetchw_be_rh850
+#define helper_atomic_or_fetchw_be helper_atomic_or_fetchw_be_rh850
+#define helper_atomic_xor_fetchw_be helper_atomic_xor_fetchw_be_rh850
+#define helper_atomic_fetch_sminw_be helper_atomic_fetch_sminw_be_rh850
+#define helper_atomic_fetch_uminw_be helper_atomic_fetch_uminw_be_rh850
+#define helper_atomic_fetch_smaxw_be helper_atomic_fetch_smaxw_be_rh850
+#define helper_atomic_fetch_umaxw_be helper_atomic_fetch_umaxw_be_rh850
+#define helper_atomic_smin_fetchw_be helper_atomic_smin_fetchw_be_rh850
+#define helper_atomic_umin_fetchw_be helper_atomic_umin_fetchw_be_rh850
+#define helper_atomic_smax_fetchw_be helper_atomic_smax_fetchw_be_rh850
+#define helper_atomic_umax_fetchw_be helper_atomic_umax_fetchw_be_rh850
+#define helper_atomic_fetch_addw_be helper_atomic_fetch_addw_be_rh850
+#define helper_atomic_add_fetchw_be helper_atomic_add_fetchw_be_rh850
+#define helper_atomic_cmpxchgl_le helper_atomic_cmpxchgl_le_rh850
+#define helper_atomic_xchgl_le helper_atomic_xchgl_le_rh850
+#define helper_atomic_fetch_addl_le helper_atomic_fetch_addl_le_rh850
+#define helper_atomic_fetch_andl_le helper_atomic_fetch_andl_le_rh850
+#define helper_atomic_fetch_orl_le helper_atomic_fetch_orl_le_rh850
+#define helper_atomic_fetch_xorl_le helper_atomic_fetch_xorl_le_rh850
+#define helper_atomic_add_fetchl_le helper_atomic_add_fetchl_le_rh850
+#define helper_atomic_and_fetchl_le helper_atomic_and_fetchl_le_rh850
+#define helper_atomic_or_fetchl_le helper_atomic_or_fetchl_le_rh850
+#define helper_atomic_xor_fetchl_le helper_atomic_xor_fetchl_le_rh850
+#define helper_atomic_fetch_sminl_le helper_atomic_fetch_sminl_le_rh850
+#define helper_atomic_fetch_uminl_le helper_atomic_fetch_uminl_le_rh850
+#define helper_atomic_fetch_smaxl_le helper_atomic_fetch_smaxl_le_rh850
+#define helper_atomic_fetch_umaxl_le helper_atomic_fetch_umaxl_le_rh850
+#define helper_atomic_smin_fetchl_le helper_atomic_smin_fetchl_le_rh850
+#define helper_atomic_umin_fetchl_le helper_atomic_umin_fetchl_le_rh850
+#define helper_atomic_smax_fetchl_le helper_atomic_smax_fetchl_le_rh850
+#define helper_atomic_umax_fetchl_le helper_atomic_umax_fetchl_le_rh850
+#define helper_atomic_cmpxchgl_be helper_atomic_cmpxchgl_be_rh850
+#define helper_atomic_xchgl_be helper_atomic_xchgl_be_rh850
+#define helper_atomic_fetch_andl_be helper_atomic_fetch_andl_be_rh850
+#define helper_atomic_fetch_orl_be helper_atomic_fetch_orl_be_rh850
+#define helper_atomic_fetch_xorl_be helper_atomic_fetch_xorl_be_rh850
+#define helper_atomic_and_fetchl_be helper_atomic_and_fetchl_be_rh850
+#define helper_atomic_or_fetchl_be helper_atomic_or_fetchl_be_rh850
+#define helper_atomic_xor_fetchl_be helper_atomic_xor_fetchl_be_rh850
+#define helper_atomic_fetch_sminl_be helper_atomic_fetch_sminl_be_rh850
+#define helper_atomic_fetch_uminl_be helper_atomic_fetch_uminl_be_rh850
+#define helper_atomic_fetch_smaxl_be helper_atomic_fetch_smaxl_be_rh850
+#define helper_atomic_fetch_umaxl_be helper_atomic_fetch_umaxl_be_rh850
+#define helper_atomic_smin_fetchl_be helper_atomic_smin_fetchl_be_rh850
+#define helper_atomic_umin_fetchl_be helper_atomic_umin_fetchl_be_rh850
+#define helper_atomic_smax_fetchl_be helper_atomic_smax_fetchl_be_rh850
+#define helper_atomic_umax_fetchl_be helper_atomic_umax_fetchl_be_rh850
+#define helper_atomic_fetch_addl_be helper_atomic_fetch_addl_be_rh850
+#define helper_atomic_add_fetchl_be helper_atomic_add_fetchl_be_rh850
+#define helper_atomic_cmpxchgq_le helper_atomic_cmpxchgq_le_rh850
+#define helper_atomic_xchgq_le helper_atomic_xchgq_le_rh850
+#define helper_atomic_fetch_addq_le helper_atomic_fetch_addq_le_rh850
+#define helper_atomic_fetch_andq_le helper_atomic_fetch_andq_le_rh850
+#define helper_atomic_fetch_orq_le helper_atomic_fetch_orq_le_rh850
+#define helper_atomic_fetch_xorq_le helper_atomic_fetch_xorq_le_rh850
+#define helper_atomic_add_fetchq_le helper_atomic_add_fetchq_le_rh850
+#define helper_atomic_and_fetchq_le helper_atomic_and_fetchq_le_rh850
+#define helper_atomic_or_fetchq_le helper_atomic_or_fetchq_le_rh850
+#define helper_atomic_xor_fetchq_le helper_atomic_xor_fetchq_le_rh850
+#define helper_atomic_fetch_sminq_le helper_atomic_fetch_sminq_le_rh850
+#define helper_atomic_fetch_uminq_le helper_atomic_fetch_uminq_le_rh850
+#define helper_atomic_fetch_smaxq_le helper_atomic_fetch_smaxq_le_rh850
+#define helper_atomic_fetch_umaxq_le helper_atomic_fetch_umaxq_le_rh850
+#define helper_atomic_smin_fetchq_le helper_atomic_smin_fetchq_le_rh850
+#define helper_atomic_umin_fetchq_le helper_atomic_umin_fetchq_le_rh850
+#define helper_atomic_smax_fetchq_le helper_atomic_smax_fetchq_le_rh850
+#define helper_atomic_umax_fetchq_le helper_atomic_umax_fetchq_le_rh850
+#define helper_atomic_cmpxchgq_be helper_atomic_cmpxchgq_be_rh850
+#define helper_atomic_xchgq_be helper_atomic_xchgq_be_rh850
+#define helper_atomic_fetch_andq_be helper_atomic_fetch_andq_be_rh850
+#define helper_atomic_fetch_orq_be helper_atomic_fetch_orq_be_rh850
+#define helper_atomic_fetch_xorq_be helper_atomic_fetch_xorq_be_rh850
+#define helper_atomic_and_fetchq_be helper_atomic_and_fetchq_be_rh850
+#define helper_atomic_or_fetchq_be helper_atomic_or_fetchq_be_rh850
+#define helper_atomic_xor_fetchq_be helper_atomic_xor_fetchq_be_rh850
+#define helper_atomic_fetch_sminq_be helper_atomic_fetch_sminq_be_rh850
+#define helper_atomic_fetch_uminq_be helper_atomic_fetch_uminq_be_rh850
+#define helper_atomic_fetch_smaxq_be helper_atomic_fetch_smaxq_be_rh850
+#define helper_atomic_fetch_umaxq_be helper_atomic_fetch_umaxq_be_rh850
+#define helper_atomic_smin_fetchq_be helper_atomic_smin_fetchq_be_rh850
+#define helper_atomic_umin_fetchq_be helper_atomic_umin_fetchq_be_rh850
+#define helper_atomic_smax_fetchq_be helper_atomic_smax_fetchq_be_rh850
+#define helper_atomic_umax_fetchq_be helper_atomic_umax_fetchq_be_rh850
+#define helper_atomic_fetch_addq_be helper_atomic_fetch_addq_be_rh850
+#define helper_atomic_add_fetchq_be helper_atomic_add_fetchq_be_rh850
+#define cpu_ldub_code cpu_ldub_code_rh850
+#define cpu_lduw_code cpu_lduw_code_rh850
+#define cpu_ldl_code cpu_ldl_code_rh850
+#define cpu_ldq_code cpu_ldq_code_rh850
+#define helper_div_i32 helper_div_i32_rh850
+#define helper_rem_i32 helper_rem_i32_rh850
+#define helper_divu_i32 helper_divu_i32_rh850
+#define helper_remu_i32 helper_remu_i32_rh850
+#define helper_shl_i64 helper_shl_i64_rh850
+#define helper_shr_i64 helper_shr_i64_rh850
+#define helper_sar_i64 helper_sar_i64_rh850
+#define helper_div_i64 helper_div_i64_rh850
+#define helper_rem_i64 helper_rem_i64_rh850
+#define helper_divu_i64 helper_divu_i64_rh850
+#define helper_remu_i64 helper_remu_i64_rh850
+#define helper_muluh_i64 helper_muluh_i64_rh850
+#define helper_mulsh_i64 helper_mulsh_i64_rh850
+#define helper_clz_i32 helper_clz_i32_rh850
+#define helper_ctz_i32 helper_ctz_i32_rh850
+#define helper_clz_i64 helper_clz_i64_rh850
+#define helper_ctz_i64 helper_ctz_i64_rh850
+#define helper_clrsb_i32 helper_clrsb_i32_rh850
+#define helper_clrsb_i64 helper_clrsb_i64_rh850
+#define helper_ctpop_i32 helper_ctpop_i32_rh850
+#define helper_ctpop_i64 helper_ctpop_i64_rh850
+#define helper_lookup_tb_ptr helper_lookup_tb_ptr_rh850
+#define helper_exit_atomic helper_exit_atomic_rh850
+#define helper_gvec_add8 helper_gvec_add8_rh850
+#define helper_gvec_add16 helper_gvec_add16_rh850
+#define helper_gvec_add32 helper_gvec_add32_rh850
+#define helper_gvec_add64 helper_gvec_add64_rh850
+#define helper_gvec_adds8 helper_gvec_adds8_rh850
+#define helper_gvec_adds16 helper_gvec_adds16_rh850
+#define helper_gvec_adds32 helper_gvec_adds32_rh850
+#define helper_gvec_adds64 helper_gvec_adds64_rh850
+#define helper_gvec_sub8 helper_gvec_sub8_rh850
+#define helper_gvec_sub16 helper_gvec_sub16_rh850
+#define helper_gvec_sub32 helper_gvec_sub32_rh850
+#define helper_gvec_sub64 helper_gvec_sub64_rh850
+#define helper_gvec_subs8 helper_gvec_subs8_rh850
+#define helper_gvec_subs16 helper_gvec_subs16_rh850
+#define helper_gvec_subs32 helper_gvec_subs32_rh850
+#define helper_gvec_subs64 helper_gvec_subs64_rh850
+#define helper_gvec_mul8 helper_gvec_mul8_rh850
+#define helper_gvec_mul16 helper_gvec_mul16_rh850
+#define helper_gvec_mul32 helper_gvec_mul32_rh850
+#define helper_gvec_mul64 helper_gvec_mul64_rh850
+#define helper_gvec_muls8 helper_gvec_muls8_rh850
+#define helper_gvec_muls16 helper_gvec_muls16_rh850
+#define helper_gvec_muls32 helper_gvec_muls32_rh850
+#define helper_gvec_muls64 helper_gvec_muls64_rh850
+#define helper_gvec_neg8 helper_gvec_neg8_rh850
+#define helper_gvec_neg16 helper_gvec_neg16_rh850
+#define helper_gvec_neg32 helper_gvec_neg32_rh850
+#define helper_gvec_neg64 helper_gvec_neg64_rh850
+#define helper_gvec_abs8 helper_gvec_abs8_rh850
+#define helper_gvec_abs16 helper_gvec_abs16_rh850
+#define helper_gvec_abs32 helper_gvec_abs32_rh850
+#define helper_gvec_abs64 helper_gvec_abs64_rh850
+#define helper_gvec_mov helper_gvec_mov_rh850
+#define helper_gvec_dup64 helper_gvec_dup64_rh850
+#define helper_gvec_dup32 helper_gvec_dup32_rh850
+#define helper_gvec_dup16 helper_gvec_dup16_rh850
+#define helper_gvec_dup8 helper_gvec_dup8_rh850
+#define helper_gvec_not helper_gvec_not_rh850
+#define helper_gvec_and helper_gvec_and_rh850
+#define helper_gvec_or helper_gvec_or_rh850
+#define helper_gvec_xor helper_gvec_xor_rh850
+#define helper_gvec_andc helper_gvec_andc_rh850
+#define helper_gvec_orc helper_gvec_orc_rh850
+#define helper_gvec_nand helper_gvec_nand_rh850
+#define helper_gvec_nor helper_gvec_nor_rh850
+#define helper_gvec_eqv helper_gvec_eqv_rh850
+#define helper_gvec_ands helper_gvec_ands_rh850
+#define helper_gvec_xors helper_gvec_xors_rh850
+#define helper_gvec_ors helper_gvec_ors_rh850
+#define helper_gvec_shl8i helper_gvec_shl8i_rh850
+#define helper_gvec_shl16i helper_gvec_shl16i_rh850
+#define helper_gvec_shl32i helper_gvec_shl32i_rh850
+#define helper_gvec_shl64i helper_gvec_shl64i_rh850
+#define helper_gvec_shr8i helper_gvec_shr8i_rh850
+#define helper_gvec_shr16i helper_gvec_shr16i_rh850
+#define helper_gvec_shr32i helper_gvec_shr32i_rh850
+#define helper_gvec_shr64i helper_gvec_shr64i_rh850
+#define helper_gvec_sar8i helper_gvec_sar8i_rh850
+#define helper_gvec_sar16i helper_gvec_sar16i_rh850
+#define helper_gvec_sar32i helper_gvec_sar32i_rh850
+#define helper_gvec_sar64i helper_gvec_sar64i_rh850
+#define helper_gvec_shl8v helper_gvec_shl8v_rh850
+#define helper_gvec_shl16v helper_gvec_shl16v_rh850
+#define helper_gvec_shl32v helper_gvec_shl32v_rh850
+#define helper_gvec_shl64v helper_gvec_shl64v_rh850
+#define helper_gvec_shr8v helper_gvec_shr8v_rh850
+#define helper_gvec_shr16v helper_gvec_shr16v_rh850
+#define helper_gvec_shr32v helper_gvec_shr32v_rh850
+#define helper_gvec_shr64v helper_gvec_shr64v_rh850
+#define helper_gvec_sar8v helper_gvec_sar8v_rh850
+#define helper_gvec_sar16v helper_gvec_sar16v_rh850
+#define helper_gvec_sar32v helper_gvec_sar32v_rh850
+#define helper_gvec_sar64v helper_gvec_sar64v_rh850
+#define helper_gvec_eq8 helper_gvec_eq8_rh850
+#define helper_gvec_ne8 helper_gvec_ne8_rh850
+#define helper_gvec_lt8 helper_gvec_lt8_rh850
+#define helper_gvec_le8 helper_gvec_le8_rh850
+#define helper_gvec_ltu8 helper_gvec_ltu8_rh850
+#define helper_gvec_leu8 helper_gvec_leu8_rh850
+#define helper_gvec_eq16 helper_gvec_eq16_rh850
+#define helper_gvec_ne16 helper_gvec_ne16_rh850
+#define helper_gvec_lt16 helper_gvec_lt16_rh850
+#define helper_gvec_le16 helper_gvec_le16_rh850
+#define helper_gvec_ltu16 helper_gvec_ltu16_rh850
+#define helper_gvec_leu16 helper_gvec_leu16_rh850
+#define helper_gvec_eq32 helper_gvec_eq32_rh850
+#define helper_gvec_ne32 helper_gvec_ne32_rh850
+#define helper_gvec_lt32 helper_gvec_lt32_rh850
+#define helper_gvec_le32 helper_gvec_le32_rh850
+#define helper_gvec_ltu32 helper_gvec_ltu32_rh850
+#define helper_gvec_leu32 helper_gvec_leu32_rh850
+#define helper_gvec_eq64 helper_gvec_eq64_rh850
+#define helper_gvec_ne64 helper_gvec_ne64_rh850
+#define helper_gvec_lt64 helper_gvec_lt64_rh850
+#define helper_gvec_le64 helper_gvec_le64_rh850
+#define helper_gvec_ltu64 helper_gvec_ltu64_rh850
+#define helper_gvec_leu64 helper_gvec_leu64_rh850
+#define helper_gvec_ssadd8 helper_gvec_ssadd8_rh850
+#define helper_gvec_ssadd16 helper_gvec_ssadd16_rh850
+#define helper_gvec_ssadd32 helper_gvec_ssadd32_rh850
+#define helper_gvec_ssadd64 helper_gvec_ssadd64_rh850
+#define helper_gvec_sssub8 helper_gvec_sssub8_rh850
+#define helper_gvec_sssub16 helper_gvec_sssub16_rh850
+#define helper_gvec_sssub32 helper_gvec_sssub32_rh850
+#define helper_gvec_sssub64 helper_gvec_sssub64_rh850
+#define helper_gvec_usadd8 helper_gvec_usadd8_rh850
+#define helper_gvec_usadd16 helper_gvec_usadd16_rh850
+#define helper_gvec_usadd32 helper_gvec_usadd32_rh850
+#define helper_gvec_usadd64 helper_gvec_usadd64_rh850
+#define helper_gvec_ussub8 helper_gvec_ussub8_rh850
+#define helper_gvec_ussub16 helper_gvec_ussub16_rh850
+#define helper_gvec_ussub32 helper_gvec_ussub32_rh850
+#define helper_gvec_ussub64 helper_gvec_ussub64_rh850
+#define helper_gvec_smin8 helper_gvec_smin8_rh850
+#define helper_gvec_smin16 helper_gvec_smin16_rh850
+#define helper_gvec_smin32 helper_gvec_smin32_rh850
+#define helper_gvec_smin64 helper_gvec_smin64_rh850
+#define helper_gvec_smax8 helper_gvec_smax8_rh850
+#define helper_gvec_smax16 helper_gvec_smax16_rh850
+#define helper_gvec_smax32 helper_gvec_smax32_rh850
+#define helper_gvec_smax64 helper_gvec_smax64_rh850
+#define helper_gvec_umin8 helper_gvec_umin8_rh850
+#define helper_gvec_umin16 helper_gvec_umin16_rh850
+#define helper_gvec_umin32 helper_gvec_umin32_rh850
+#define helper_gvec_umin64 helper_gvec_umin64_rh850
+#define helper_gvec_umax8 helper_gvec_umax8_rh850
+#define helper_gvec_umax16 helper_gvec_umax16_rh850
+#define helper_gvec_umax32 helper_gvec_umax32_rh850
+#define helper_gvec_umax64 helper_gvec_umax64_rh850
+#define helper_gvec_bitsel helper_gvec_bitsel_rh850
+#define cpu_restore_state cpu_restore_state_rh850
+#define page_collection_lock page_collection_lock_rh850
+#define page_collection_unlock page_collection_unlock_rh850
+#define free_code_gen_buffer free_code_gen_buffer_rh850
+#define tcg_exec_init tcg_exec_init_rh850
+#define tb_cleanup tb_cleanup_rh850
+#define tb_flush tb_flush_rh850
+#define tb_phys_invalidate tb_phys_invalidate_rh850
+#define tb_gen_code tb_gen_code_rh850
+#define tb_exec_lock tb_exec_lock_rh850
+#define tb_exec_unlock tb_exec_unlock_rh850
+#define tb_invalidate_phys_page_range tb_invalidate_phys_page_range_rh850
+#define tb_invalidate_phys_range tb_invalidate_phys_range_rh850
+#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_rh850
+#define tb_check_watchpoint tb_check_watchpoint_rh850
+#define cpu_io_recompile cpu_io_recompile_rh850
+#define tb_flush_jmp_cache tb_flush_jmp_cache_rh850
+#define tcg_flush_softmmu_tlb tcg_flush_softmmu_tlb_rh850
+#define translator_loop_temp_check translator_loop_temp_check_rh850
+#define translator_loop translator_loop_rh850
+#define helper_atomic_cmpxchgo_le_mmu helper_atomic_cmpxchgo_le_mmu_rh850
+#define helper_atomic_cmpxchgo_be_mmu helper_atomic_cmpxchgo_be_mmu_rh850
+#define helper_atomic_ldo_le_mmu helper_atomic_ldo_le_mmu_rh850
+#define helper_atomic_ldo_be_mmu helper_atomic_ldo_be_mmu_rh850
+#define helper_atomic_sto_le_mmu helper_atomic_sto_le_mmu_rh850
+#define helper_atomic_sto_be_mmu helper_atomic_sto_be_mmu_rh850
+#define unassigned_mem_ops unassigned_mem_ops_rh850
+#define floatx80_infinity floatx80_infinity_rh850
+#define dup_const_func dup_const_func_rh850
+#define gen_helper_raise_exception gen_helper_raise_exception_rh850
+#define gen_helper_raise_interrupt gen_helper_raise_interrupt_rh850
+#define gen_helper_vfp_get_fpscr gen_helper_vfp_get_fpscr_rh850
+#define gen_helper_vfp_set_fpscr gen_helper_vfp_set_fpscr_rh850
+#define gen_helper_cpsr_read gen_helper_cpsr_read_rh850
+#define gen_helper_cpsr_write gen_helper_cpsr_write_rh850
+#define restore_state_to_opc restore_state_to_opc_rh850
+#define helper_tlb_flush helper_tlb_flush_rh850
+#define helper_uc_rh850_exit helper_uc_rh850_exit_rh850
+#define gen_intermediate_code gen_intermediate_code_rh850
+#endif
diff --git a/qemu/target/rh850/Makefile.objs b/qemu/target/rh850/Makefile.objs
new file mode 100644
index 0000000000..aaa7c0cc64
--- /dev/null
+++ b/qemu/target/rh850/Makefile.objs
@@ -0,0 +1 @@
+obj-y += translate.o op_helper.o helper.o cpu.o fpu_helper.o gdbstub.o fpu_translate.o
diff --git a/qemu/target/rh850/cpu-param.h b/qemu/target/rh850/cpu-param.h
new file mode 100644
index 0000000000..24231873c3
--- /dev/null
+++ b/qemu/target/rh850/cpu-param.h
@@ -0,0 +1,11 @@
+#pragma once
+
+/* QEMU addressing/paging config */
+#define TARGET_PAGE_BITS 12 /* 4 KiB Pages */
+
+#define TARGET_LONG_BITS 32
+#define TARGET_PHYS_ADDR_SPACE_BITS 32
+#define TARGET_VIRT_ADDR_SPACE_BITS 32
+
+#define NB_MMU_MODES 4
+
diff --git a/qemu/target/rh850/cpu.c b/qemu/target/rh850/cpu.c
new file mode 100644
index 0000000000..b6b44b28d2
--- /dev/null
+++ b/qemu/target/rh850/cpu.c
@@ -0,0 +1,473 @@
+/*
+ * QEMU RH850 CPU
+ *
+ * Copyright (c) 2018-2019 iSYSTEM Labs d.o.o.
+ * Copyright (c) 2023 Quarkslab
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/ctype.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+
+/* RH850 CPU definitions */
+
+/* Program registers (rh850_prog_regnames):
+ * r0 - zero
+ * r1 - assembler reserved register
+ * r2 - real-time OS register / address and data variable register
+ * r3 - stack pointer
+ * r4 - global pointer
+ * r5 - text pointer
+ * r6-r29 - address and data variable registers
+ * r30 - element pointer
+ * r31 - link pointer
+ */
+
+const char * const rh850_gp_regnames[] = {
+  "r0-zero", "r1", "r2", "r3-sp", "r4", "r5", "r6", "r7",
+  "r8", "r9", "r10 ", "r11", "r12", "r13", "r14", "r15",
+  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r2 ",
+  "r24", "r25", "r26", "r27", "r28", "r29", "r30-ep", "r31-lp"
+};
+
+// Basic system registers
+const char * const rh850_sys_regnames[][MAX_SYS_REGS_IN_BANK] = {
+
+{ // SELECTION ID 0                           [5] used to be psw, but now it is stored in flags only
+  "eipc",  "eipsw", "fepc",   "fepsw", NULL,  NULL,    "fpsr",   "fpepc", "fpst",  "fpcc",
+  "fpcfg", "fpec",  NULL,     "eiic",  "feic", NULL,    "ctpc",   "ctpsw", NULL,    NULL,
+  "ctbp",  NULL,    NULL,     NULL,    NULL,   NULL,    NULL,     NULL,    "eiwr",  "fewr",
+  NULL,    "bsel"},
+{ // SELECTION ID 1
+  "mcfg0", NULL,    "rbase",  "ebase", "intbp", "mctl", "pid",    "fpipr", NULL,    NULL,
+  NULL,    "sccfg", "scbp",
+},
+{ // SELECTION ID 2
+  "htcfg0",NULL,    NULL,     NULL,    NULL,    NULL,   "mea",    "asid",  "mei",   NULL,
+  "ispr",  "pmr",   "icsr",   "intcfg"
+},
+{ // SELECTION ID 3
+    NULL,  NULL,    NULL,     NULL,    NULL,    NULL,   NULL,     NULL,    NULL,    NULL
+},
+{ // SELECTION ID 4
+  NULL,    NULL,    NULL,     NULL,    NULL,    NULL,    NULL,     NULL,    NULL,    NULL,
+  NULL,    NULL,    NULL,     NULL,    NULL,    NULL,    "ictagl", "ictagh","icdatl","icdath",
+  NULL,    NULL,    NULL,     NULL,    "icctrl",NULL,    "iccfg",  NULL,    "icerr", NULL
+},
+{ // SELECTION ID 5
+  "mpm",   "mprc",  NULL,     NULL,    "mpbrgn","mptrgn",NULL,     NULL,    "mca",   "mcs"
+  "mcc",   "mcr"
+},
+{ // SELECTION ID 6
+  "mpla0", "mpua0", "mpat0",  NULL,    "mpla1", "mpua1", "mpat1",  NULL,    "mpla2", "mpua2",
+  "mpat2", NULL,    "mpla3",  "mpua3", "mpat3", NULL,    "mpla4",  "mpua4", "mpat4", NULL,
+  "mpla5", "mpua5", "mpat5",  NULL,    "mpla6",  "mpua6", "mpat6", NULL,    "mpla7", "mpua7",
+  "mpat7", NULL
+},
+{ // SELECTION ID 7
+    /* MPU function system registers */
+  "mpla8", "mpua8", "mpat8",  NULL,    "mpla9",  "mpua9", "mpat9", NULL,    "mpla10","mpua10",
+  "mpat10",NULL,    "mpla11", "mpua11", "mpat11",NULL,    "mpla12","mpua12","mpat12",NULL,
+  "mpla13","mpua13","mpat13", NULL,     "mpla14","mpua14","mpat14",NULL,    "mpla15","mpua15",
+  "mpat15",NULL
+}
+};
+
+// Where bits are read only, mask is set to 0
+const uint32_t rh850_sys_reg_read_only_masks[][MAX_SYS_REGS_IN_BANK] = {
+
+{	//SELECTION ID 0                                            PSW - implemented as registers for each used bit, see cpu_ZF, ...
+	0xFFFFFFFF, 0x40078EFF, 0xFFFFFFFF, 0x40078EFF, 0x0, /*0x40018EFF*/  0, 0xFFEEFFFF, 0xFFFFFFFE, 0x00003F3F, 0x000000FF,
+	0x0000031F, 0x00000001, 0x0,		0xFFFFFFFF, 0xFFFFFFFF, 0x0,		0xFFFFFFFF, 0x0000001F, 0x0,		0x0,
+	0xFFFFFFFE, 0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0xFFFFFFFF, 0xFFFFFFFF,
+	0x0, 		0x0
+},
+{	//SELECTION ID 1
+    // for MCFG (idx = 0), byte 3 seems to not be writable, at least on devicee used for testing
+	0x00000000, 0x0, 		0x00000000, 0xFFFFFE01, 0xFFFFFE00, 0x00000003, 0x00000000, 0x0000001F, 0x0, 		0x0,
+	0x0, 		0x000000FF, 0xFFFFFFFC
+},
+{	//SELECTION ID 2
+	0x00000000, 0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0xFFFFFFFF, 0x000003FF, 0x001F073F, 0x0,
+	0x00000000, 0x0000FFFF, 0x00000000, 0x00000001
+},
+{	//SELECTION ID 3
+	0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0
+},
+{	//SELECTION ID 4
+	0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0,
+	0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0xFFFFFA35, 0xF0FFFF00, 0xFFFFFFFF, 0xFFFFFFFF,
+	0x0, 		0x0, 		0x0, 		0x0, 		0x00020107, 0x0, 		0x00000000, 0x0, 		0xBF3F7FFD, 0x0
+},
+{	//SELECTION ID 5
+	0x00000003, 0x0000FFFF, 0x0, 		0x0, 		0x00000000, 0x00000000, 0x0, 		0x0, 		0xFFFFFFFF, 0xFFFFFFFF,
+	0xFFFFFFFF, 0x0000013F
+},
+{	//SELECTION ID 6
+	0xFFFFFFFC, 0xFFFFFFFC, 0x03FF00FF, 0x0, 		0xFFFFFFFC, 0xFFFFFFFC, 0x03FF00FF, 0x0, 		0xFFFFFFFC, 0xFFFFFFFF,
+	0x03FF00FF, 0x0, 		0xFFFFFFFC, 0xFFFFFFFC, 0x03FF00FF, 0x0, 		0xFFFFFFFC, 0xFFFFFFFC, 0x03FF00FF, 0x0,
+	0xFFFFFFFC, 0xFFFFFFFC, 0x03FF00FF, 0x0, 		0xFFFFFFFC, 0xFFFFFFFC, 0x03FF00FF, 0x0, 		0xFFFFFFFC, 0xFFFFFFFC,
+	0x03FF00FF, 0x0
+},
+{	//SELECTION ID 7
+	0xFFFFFFFC, 0xFFFFFFFC, 0x03FF00FF, 0x0, 		0xFFFFFFFC, 0xFFFFFFFC, 0x03FF00FF, 0x0, 		0xFFFFFFFC, 0xFFFFFFFF,
+	0x03FF00FF, 0x0, 		0xFFFFFFFC, 0xFFFFFFFC, 0x03FF00FF, 0x0, 		0xFFFFFFFC, 0xFFFFFFFC, 0x03FF00FF, 0x0,
+	0xFFFFFFFC, 0xFFFFFFFC, 0x03FF00FF, 0x0, 		0xFFFFFFFC, 0xFFFFFFFC, 0x03FF00FF, 0x0, 		0xFFFFFFFC, 0xFFFFFFFC,
+	0x03FF00FF, 0x0
+}
+};
+
+
+const uint32_t rh850_sys_reg_read_only_values[][MAX_SYS_REGS_IN_BANK] = {
+{	//SELECTION ID 0
+	0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0,
+	0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0,
+	0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0, 		0x0,
+	0x0,		0x0
+},
+{	//SELECTION ID 1
+	0x4,		0x0,		0x0,		0x0,		0x0,		0x80000000, 0x12345678, 0x0,		0x0,		0x0,
+	0x0,		0x0,		0x0
+},
+{	//SELECTION ID 2
+	0x00008000, 0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,
+	0x0,		0x0,		0x0,		0x0
+},
+{	//SELECTION ID 3
+	0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0
+},
+{	//SELECTION ID 4
+	0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,
+	0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,
+	0x0,		0x0,		0x0,		0x0,		0x00010000, 0x0,		0x00010000,	0x0,		0x0,		0x0
+},
+{	//SELECTION ID 5
+	0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,
+	0x0,		0x0
+},
+{	//SELECTION ID 6
+	0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,
+	0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,
+	0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,
+	0x0,		0x0
+},
+{	//SELECTION ID 7
+	0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,
+	0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,
+	0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,		0x0,
+	0x0,		0x0
+}
+};
+
+
+
+/*Data Buffer Operation Registers (rh850_sys_databuff_regnames):
+ * sr24, 13 - cbdcr */
+const char * const rh850_sys_databuff_regnames[] = { /* Data buffer operation registers */
+  "cbdcr"
+};
+
+const char * const rh850_excp_names[] = {
+    "misaligned_fetch",
+    "fault_fetch",
+    "illegal_instruction",
+    "breakpoint",
+    "misaligned_load",
+    "fault_load",
+    "misaligned_store",
+    "fault_store",
+    "user_ecall",
+    "supervisor_ecall",
+    "hypervisor_ecall",
+    "machine_ecall",
+    "exec_page_fault",
+    "load_page_fault",
+    "reserved",
+    "store_page_fault"
+};
+
+const char * const rh850_intr_names[] = {
+    "u_software",
+    "s_software",
+    "h_software",
+    "m_software",
+    "u_timer",
+    "s_timer",
+    "h_timer",
+    "m_timer",
+    "u_external",
+    "s_external",
+    "h_external",
+    "m_external",
+    "coprocessor",
+    "host"
+};
+
+
+void rh850_cpu_set_pc(CPUState *cs, vaddr value)
+{
+    RH850CPU *cpu = RH850_CPU(cs);
+    CPURH850State *env = &cpu->env;
+    env->pc = value;
+}
+
+vaddr rh850_cpu_get_pc(CPUState *cs)
+{
+    RH850CPU *cpu = RH850_CPU(cs);
+    CPURH850State *env = &cpu->env;
+    return env->pc;
+}
+
+AddressSpace *cpu_addressspace(CPUState *cs, MemTxAttrs attrs)
+{
+    return cpu_get_address_space(cs, cpu_asidx_from_attrs(cs, attrs));
+}
+
+
+/* called by qemu's softmmu to fill the qemu tlb */
+static bool rh850_tlb_fill(CPUState *cs, vaddr addr, int size,
+                           MMUAccessType access_type, int mmu_idx,
+                           bool probe, uintptr_t retaddr)
+{
+    int ret;
+    ret = rh850_cpu_handle_mmu_fault(cs, addr, size, access_type, mmu_idx);
+    if (ret == TRANSLATE_FAIL) {
+        RH850CPU *cpu = RH850_CPU(cs);
+        CPURH850State *env = &cpu->env;
+        do_raise_exception_err(env, cs->exception_index, retaddr);
+    }
+    return true;
+}
+
+
+static void rh850_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
+{
+    RH850CPU *cpu = RH850_CPU(cs);
+    CPURH850State *env = &cpu->env;
+    env->pc = tb->pc;
+}
+
+static bool rh850_cpu_has_work(CPUState *cs)
+{
+#ifndef CONFIG_USER_ONLY
+    return true;
+#else
+    return true;
+#endif
+}
+
+void restore_state_to_opc(CPURH850State *env, TranslationBlock *tb,
+                          target_ulong *data)
+{
+    env->pc = data[0];
+}
+
+
+static void rh850_raise_exception(CPURH850State *env, uint32_t excp,
+                           uint32_t syndrome, uint32_t target_el)
+{
+    CPUState *cs = CPU(rh850_env_get_cpu(env));
+
+    cs->exception_index = excp;
+    cpu_loop_exit(cs);
+}
+
+
+static void rh850_debug_excp_handler(CPUState *cs)
+{
+    /* Called by core code when a watchpoint or breakpoint fires;
+     * need to check which one and raise the appropriate exception.
+     */
+    RH850CPU *cpu = RH850_CPU(cs);
+    CPURH850State *env = &cpu->env;
+    CPUWatchpoint *wp_hit = cs->watchpoint_hit;
+
+    if (wp_hit) {
+        if (wp_hit->flags & BP_CPU) {
+            // bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0;
+            // bool same_el = true;
+
+            cs->watchpoint_hit = NULL;
+
+            // env->exception.fsr = arm_debug_exception_fsr(env);
+            // env->exception.vaddress = wp_hit->hitaddr;
+            rh850_raise_exception(env, 0, 0, 0);
+        }
+    } else {
+        uint64_t pc = env->pc;
+        // bool same_el = true;
+
+        /* (1) GDB breakpoints should be handled first.
+         * (2) Do not raise a CPU exception if no CPU breakpoint has fired,
+         * since singlestep is also done by generating a debug internal
+         * exception.
+         */
+        if (!cpu_breakpoint_test(cs, pc, BP_GDB)  &&
+             cpu_breakpoint_test(cs, pc, BP_CPU)) {
+
+            rh850_raise_exception(env, 0, 0, 0);
+        }
+    }
+}
+
+static bool check_watchpoints(RH850CPU *cpu)
+{
+    return true;
+}
+
+
+static bool rh850_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
+{
+    /* Called by core code when a CPU watchpoint fires; need to check if this
+     * is also an architectural watchpoint match.
+     */
+    RH850CPU *cpu = RH850_CPU(cs);
+
+    return check_watchpoints(cpu);
+}
+
+
+static void rh850_cpu_reset(CPUState *cs)
+{
+
+	RH850CPU *cpu = RH850_CPU(cs);
+    RH850CPUClass *mcc = RH850_CPU_GET_CLASS(cpu);
+    CPURH850State *env = &cpu->env;
+
+    mcc->parent_reset(cs);
+    cs->exception_index = EXCP_NONE;
+    set_default_nan_mode(1, &env->fp_status);
+    env->pc = 0; // move to direct vector ? (always 0?)
+    env->ID_flag = 1;   // interrupts are disable on reset
+    env->systemRegs[BANK_ID_BASIC_0][EIPSW_IDX] = 0x20;
+    env->systemRegs[BANK_ID_BASIC_0][FEPSW_IDX] = 0x20;
+    env->systemRegs[BANK_ID_BASIC_0][EIIC_IDX] = 0x0;
+    env->systemRegs[BANK_ID_BASIC_0][FEIC_IDX] = 0x0;
+    env->systemRegs[BANK_ID_BASIC_0][PSW_IDX] = 0x20; // reset value of PSW
+    env->systemRegs[BANK_ID_BASIC_0][CTPSW_IDX] = 0;
+    env->systemRegs[BANK_ID_BASIC_0][CTBP_IDX] = 0;   // only bit 0 must be set to 0
+    env->systemRegs[BANK_ID_BASIC_2][ASID_IDX2] = 0;   // only bits 31-10 must be set to 0
+    env->systemRegs[BANK_ID_BASIC_2][HTCFG0_IDX2] = 0x00018000;   // const value
+    env->systemRegs[BANK_ID_BASIC_2][MEI_IDX2] = 0;    // only some bits must be 0
+    env->systemRegs[BANK_ID_BASIC_1][RBASE_IDX1] = 0;
+    env->systemRegs[BANK_ID_BASIC_1][EBASE_IDX1] = 0;  // only bits 8-1 must be 0
+    env->systemRegs[BANK_ID_BASIC_1][INTBP_IDX1] = 0;  // only bits 8-0 must be 0
+    env->systemRegs[BANK_ID_BASIC_1][PID_IDX1] = 0x05000120;  // const
+    env->systemRegs[BANK_ID_BASIC_1][SCCFG_IDX1] = 0;  // bits 31-8 must be 0
+    env->systemRegs[BANK_ID_BASIC_1][SCBP_IDX1] = 0;  // bits 1-0 must be 0
+    env->systemRegs[BANK_ID_BASIC_1][MCFG0_IDX1] = 0x4;  // bits 31-8 must be 0
+    env->systemRegs[BANK_ID_BASIC_1][MCTL_IDX1] = 0x80000000;  // bits 31-8 must be 0
+
+    env->systemRegs[BANK_ID_BASIC_2][FPIPR_IDX1] = 0;
+    env->systemRegs[BANK_ID_BASIC_2][ISPR_IDX2] = 0;
+    env->systemRegs[BANK_ID_BASIC_2][PMR_IDX2] = 0;
+    env->systemRegs[BANK_ID_BASIC_2][ICSR_IDX2] = 0;
+    env->systemRegs[BANK_ID_BASIC_2][INTCFG_IDX2] = 0;
+}
+
+static void rh850_cpu_realize(struct uc_struct *uc, CPUState *dev)
+{
+    CPUState *cs = CPU(dev);
+
+    cpu_exec_realizefn(cs);
+    
+    qemu_init_vcpu(cs);
+    
+    cpu_reset(cs);
+}
+
+static void rh850_cpu_init(struct uc_struct *uc, CPUState *obj)
+{
+    CPUState *cs = CPU(obj);
+    RH850CPU *cpu = RH850_CPU(obj);
+
+    /* Set CPU pointers. */
+    cpu_set_cpustate_pointers(cpu);
+
+    cs->env_ptr = &cpu->env;
+    cpu->env.uc = uc;
+}
+
+static void rh850_cpu_class_init(struct uc_struct *uc, CPUClass *c)
+{
+    RH850CPUClass *mcc = RH850_CPU_CLASS(c);
+    CPUClass *cc = CPU_CLASS(c);
+
+    mcc->parent_reset = cc->reset;
+    cc->reset = rh850_cpu_reset;
+
+    cc->has_work = rh850_cpu_has_work;
+    cc->do_interrupt = rh850_cpu_do_interrupt;
+    cc->cpu_exec_interrupt = rh850_cpu_exec_interrupt;
+    cc->set_pc = rh850_cpu_set_pc;
+    cc->tlb_fill = rh850_tlb_fill;
+    cc->synchronize_from_tb = rh850_cpu_synchronize_from_tb;
+    cc->debug_excp_handler = rh850_debug_excp_handler;
+    cc->debug_check_watchpoint = rh850_debug_check_watchpoint;
+
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = rh850_cpu_handle_mmu_fault;
+#else
+    cc->do_unaligned_access = rh850_cpu_do_unaligned_access;
+    cc->get_phys_page_debug = rh850_cpu_get_phys_page_debug;
+#endif
+#ifdef CONFIG_TCG
+    cc->tcg_initialize = rh850_translate_init;
+#endif
+}
+
+RH850CPU *cpu_rh850_init(struct uc_struct *uc, const char *cpu_model)
+{
+    RH850CPU *cpu;
+    CPUState *cs;
+    CPUClass *cc;
+
+    cpu = calloc(1, sizeof(*cpu));
+    if (cpu == NULL) {
+        return NULL;
+    }
+
+    cs = (CPUState *)cpu;
+    cc = (CPUClass *)&cpu->cc;
+    cs->cc = cc;
+    cs->uc = uc;
+    uc->cpu = (CPUState *)cpu;
+
+    /* init CPUClass */
+    cpu_class_init(uc, cc);
+
+    /* init CPUClass */
+    rh850_cpu_class_init(uc, cc);
+
+    /* init CPUState */
+    cpu_common_initfn(uc, cs);
+
+    /* init CPU */
+    rh850_cpu_init(uc, cs);
+
+    /* realize CPU */
+    rh850_cpu_realize(uc, cs);
+
+    // init addresss space
+    cpu_address_space_init(cs, 0, cs->memory);
+
+    return cpu;
+}
+
+
+
+
diff --git a/qemu/target/rh850/cpu.h b/qemu/target/rh850/cpu.h
new file mode 100644
index 0000000000..c54ad11599
--- /dev/null
+++ b/qemu/target/rh850/cpu.h
@@ -0,0 +1,276 @@
+/*
+ * QEMU RH850 CPU
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2017-2018 SiFive, Inc.
+ * Copyright (c) 2023 Quarkslab
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RH850_CPU_H
+#define RH850_CPU_H
+
+#define TCG_GUEST_DEFAULT_MO 0
+
+//#define TARGET_INSN_START_EXTRA_WORDS 2
+
+#define ELF_MACHINE EM_RH850
+#define CPUArchState struct CPURH850State
+
+#include "qemu-common.h"
+#include "hw/core/cpu.h"
+#include "exec/cpu-defs.h"
+#include "fpu/softfloat.h"
+
+#define TYPE_RH850_CPU "rh850-cpu"
+
+#define RH850_CPU_TYPE_SUFFIX "-" TYPE_RH850_CPU
+#define RH850_CPU_TYPE_NAME(name) (name RH850_CPU_TYPE_SUFFIX)
+#define CPU_RESOLVING_TYPE TYPE_RH850_CPU
+#define TYPE_RH850_CPU_ANY              RH850_CPU_TYPE_NAME("any")
+
+#define RV32 ((target_ulong)1 << (TARGET_LONG_BITS - 2))
+#define RV64 ((target_ulong)2 << (TARGET_LONG_BITS - 2))
+
+#if defined(TARGET_RH850)
+#define RVXLEN RV32
+#elif defined(TARGET_RH85064)
+#define RVXLEN RV64
+#endif
+
+#define RV(x) ((target_ulong)1 << (x - 'A'))
+
+#define RVI RV('I')
+#define RVM RV('M')
+#define RVA RV('A')
+#define RVF RV('F')
+#define RVD RV('D')
+#define RVC RV('C')
+#define RVS RV('S')
+#define RVU RV('U')
+
+/* S extension denotes that Supervisor mode exists, however it is possible
+   to have a core that support S mode but does not have an MMU and there
+   is currently no bit in misa to indicate whether an MMU exists or not
+   so a cpu features bitfield is required */
+enum {
+    RH850_FEATURE_MMU
+};
+
+#define USER_VERSION_2_02_0 0x00020200
+#define PRIV_VERSION_1_09_1 0x00010901
+#define PRIV_VERSION_1_10_0 0x00011000
+
+#define TRANSLATE_FAIL 1
+#define TRANSLATE_SUCCESS 0
+#define MMU_USER_IDX 3
+
+#define MAX_RH850_PMPS (16)
+
+typedef struct CPURH850State CPURH850State;
+
+#include "pmp.h"
+
+#include "register_indices.h"
+
+#define NUM_GP_REGS 32
+#define NUM_SYS_REG_BANKS 7
+#define MAX_SYS_REGS_IN_BANK 32
+#define BANK_ID_BASIC_0 0
+#define BANK_ID_BASIC_1 1
+#define BANK_ID_BASIC_2 2
+
+struct CPURH850State {
+
+
+    target_ulong gpRegs[NUM_GP_REGS];
+    target_ulong pc;
+    target_ulong sysDatabuffRegs[1];
+    target_ulong systemRegs[NUM_SYS_REG_BANKS][MAX_SYS_REGS_IN_BANK];
+    //target_ulong sysBasicRegs[31];
+    //target_ulong sysInterruptRegs[5];
+    //uint64_t sysFpuRegs[6];  //using rh850 basic system registers(sr6-sr11), 32-bit or 64-bit precision
+    //target_ulong sysMpuRegs[56];
+    //target_ulong sysCacheRegs[7];
+
+    // flags contained in PSW register
+    uint32_t Z_flag;
+    uint32_t S_flag;
+    uint32_t OV_flag;
+    uint32_t CY_flag;
+    uint32_t SAT_flag;
+    uint32_t ID_flag;
+    uint32_t EP_flag;
+    uint32_t NP_flag;
+    uint32_t EBV_flag;
+    uint32_t CU0_flag;
+    uint32_t CU1_flag;
+    uint32_t CU2_flag;
+    uint32_t UM_flag;
+
+       uint32_t features;
+    uint32_t badaddr;
+
+    target_ulong cpu_LLbit;     // register for mutual exclusion (LDL.W, STC.W)
+    target_ulong cpu_LLAddress;     // register for mutual exclusion (LDL.W, STC.W)
+
+    target_ulong load_res;      // inst addr for TCG
+    target_ulong load_val;      // inst val for TCG
+
+    float_status fp_status;     // not used yet in rh850, left for floating-point support.
+
+    target_ulong fpsr;      /* floating-point configuration/status register. */
+
+    uint32_t exception_cause;
+    int exception_priority;
+    bool exception_dv;  
+
+    // Unicorn engine
+    struct uc_struct *uc;
+};
+
+#define RH850_CPU(obj) ((RH850CPU *)obj)
+#define RH850_CPU_CLASS(klass) ((RH850CPUClass *)klass)
+#define RH850_CPU_GET_CLASS(obj) (&((RH850CPU *)obj)->cc)
+
+
+/**
+ * RH850CPUClass:
+ * @parent_realize: The parent class' realize handler.
+ * @parent_reset: The parent class' reset handler.
+ *
+ * A RH850 CPU model.
+ */
+typedef struct RH850CPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+    void (*parent_reset)(CPUState *cpu);
+} RH850CPUClass;
+
+/**
+ * RH850CPU:
+ * @env: #CPURH850State
+ *
+ * A RH850 CPU.
+ */
+typedef struct RH850CPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+    CPUNegativeOffsetState neg;
+    CPURH850State env;
+
+    RH850CPUClass cc;
+} RH850CPU;
+
+typedef RH850CPU ArchCPU;
+
+static inline RH850CPU *rh850_env_get_cpu(CPURH850State *env)
+{
+    return container_of(env, RH850CPU, env);
+}
+
+static inline int rh850_has_ext(CPURH850State *env, target_ulong ext)
+{		// TODO: what does value 'ext' represent??
+    //return (env->misa & ext) != 0;
+	return true;
+}
+
+static inline bool rh850_feature(CPURH850State *env, int feature)
+{
+    return env->features & (1ULL << feature);
+}
+
+#include "cpu_user.h"
+#include "cpu_bits.h"
+
+extern const char * const rh850_gp_regnames[];
+extern const char * const rh850_sys_regnames[][MAX_SYS_REGS_IN_BANK];
+extern const char * const rh850_sys_databuff_regnames[];
+
+extern const char * const rh850_excp_names[];
+extern const char * const rh850_intr_names[];
+extern const uint32_t rh850_sys_reg_read_only_values[][MAX_SYS_REGS_IN_BANK];
+extern const uint32_t rh850_sys_reg_read_only_masks[][MAX_SYS_REGS_IN_BANK];
+
+#define ENV_GET_CPU(e) CPU(rh850_env_get_cpu(e))
+#define ENV_OFFSET offsetof(RH850CPU, env)
+
+void rh850_cpu_do_interrupt(CPUState *cpu);
+int rh850_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int rh850_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+bool rh850_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
+int rh850_cpu_mmu_index(CPURH850State *env, bool ifetch);
+hwaddr rh850_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+void  rh850_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
+                                    MMUAccessType access_type, int mmu_idx,
+                                    uintptr_t retaddr);
+int rh850_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size,
+                              int rw, int mmu_idx);
+
+char *rh850_isa_string(RH850CPU *cpu);
+void rh850_cpu_list(void);
+
+#define cpu_init(cpu_model) cpu_generic_init(TYPE_RH850_CPU, cpu_model)
+#define cpu_signal_handler cpu_rh850_signal_handler
+#define cpu_list rh850_cpu_list
+#define cpu_mmu_index rh850_cpu_mmu_index
+
+void rh850_set_mode(CPURH850State *env, target_ulong newpriv);
+
+void rh850_translate_init(struct uc_struct *uc);
+RH850CPU *cpu_rh850_init(struct uc_struct *uc, const char *cpu_model);
+int cpu_rh850_signal_handler(int host_signum, void *pinfo, void *puc);
+void QEMU_NORETURN do_raise_exception_err(CPURH850State *env,
+                                          uint32_t exception, uintptr_t pc);
+
+target_ulong cpu_rh850_get_fflags(CPURH850State *env);
+void cpu_rh850_set_fflags(CPURH850State *env, target_ulong);
+void rh850_cpu_set_pc(CPUState *cs, vaddr value);
+vaddr rh850_cpu_get_pc(CPUState *cs);
+AddressSpace *cpu_addressspace(CPUState *cs, MemTxAttrs attrs);
+
+#define TB_FLAGS_MMU_MASK  3
+#define TB_FLAGS_FP_ENABLE MSTATUS_FS
+
+/*
+ * This f. is called from  tcg_gen_lookup_and_goto_ptr() to obtain PC
+ * which is then used for TB lookup.
+ */
+static inline void cpu_get_tb_cpu_state(CPURH850State *env, target_ulong *pc,
+                                        target_ulong *cs_base, uint32_t *flags)
+{
+    *pc = env->pc;
+    *cs_base = 0;
+#ifdef CONFIG_USER_ONLY
+    *flags = TB_FLAGS_FP_ENABLE;
+#else
+    *flags = cpu_mmu_index(env, 0);
+#endif
+}
+
+void csr_write_helper(CPURH850State *env, target_ulong val_to_write,
+        target_ulong csrno);
+target_ulong csr_read_helper(CPURH850State *env, target_ulong csrno);
+
+#ifndef CONFIG_USER_ONLY
+void rh850_set_local_interrupt(RH850CPU *cpu, target_ulong mask, int value);
+#endif
+
+extern const int NUM_GDB_REGS;
+
+#include "exec/cpu-all.h"
+
+#endif /* RH850_CPU_H */
diff --git a/qemu/target/rh850/cpu_bits.h b/qemu/target/rh850/cpu_bits.h
new file mode 100644
index 0000000000..a3b90298a6
--- /dev/null
+++ b/qemu/target/rh850/cpu_bits.h
@@ -0,0 +1,431 @@
+/* RH850 PSW constants */
+
+#define PSW_Z 	0x00000001
+#define PSW_S 	0x00000002
+#define PSW_OV 	0x00000004
+#define PSW_CY 	0x00000008
+#define PSW_SAT	0x00000010
+#define PSW_ID	0x00000020
+#define PSW_EP  0x00000040
+#define PSW_NP	0x00000080
+#define PSW_EBV	0x00008000
+#define PSW_CU0	0x00010000
+#define PSW_UM	0x40000000
+
+/*  */
+
+/* RH850 ISA constants */
+
+#define get_field(reg, mask) (((reg) & \
+                 (target_ulong)(mask)) / ((mask) & ~((mask) << 1)))
+#define set_field(reg, mask, val) (((reg) & ~(target_ulong)(mask)) | \
+                 (((target_ulong)(val) * ((mask) & ~((mask) << 1))) & \
+                 (target_ulong)(mask)))
+
+#define PGSHIFT 12
+
+#define FSR_RD_SHIFT 5
+#define FSR_RD   (0x7 << FSR_RD_SHIFT)
+
+#define FPEXC_NX 0x01
+#define FPEXC_UF 0x02
+#define FPEXC_OF 0x04
+#define FPEXC_DZ 0x08
+#define FPEXC_NV 0x10
+
+#define FSR_AEXC_SHIFT 0
+#define FSR_NVA  (FPEXC_NV << FSR_AEXC_SHIFT)
+#define FSR_OFA  (FPEXC_OF << FSR_AEXC_SHIFT)
+#define FSR_UFA  (FPEXC_UF << FSR_AEXC_SHIFT)
+#define FSR_DZA  (FPEXC_DZ << FSR_AEXC_SHIFT)
+#define FSR_NXA  (FPEXC_NX << FSR_AEXC_SHIFT)
+#define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
+
+/* CSR numbers */
+#define CSR_FFLAGS 0x1
+#define CSR_FRM 0x2
+#define CSR_FCSR 0x3
+#define CSR_CYCLE 0xc00
+#define CSR_TIME 0xc01
+#define CSR_INSTRET 0xc02
+#define CSR_HPMCOUNTER3 0xc03
+#define CSR_HPMCOUNTER4 0xc04
+#define CSR_HPMCOUNTER5 0xc05
+#define CSR_HPMCOUNTER6 0xc06
+#define CSR_HPMCOUNTER7 0xc07
+#define CSR_HPMCOUNTER8 0xc08
+#define CSR_HPMCOUNTER9 0xc09
+#define CSR_HPMCOUNTER10 0xc0a
+#define CSR_HPMCOUNTER11 0xc0b
+#define CSR_HPMCOUNTER12 0xc0c
+#define CSR_HPMCOUNTER13 0xc0d
+#define CSR_HPMCOUNTER14 0xc0e
+#define CSR_HPMCOUNTER15 0xc0f
+#define CSR_HPMCOUNTER16 0xc10
+#define CSR_HPMCOUNTER17 0xc11
+#define CSR_HPMCOUNTER18 0xc12
+#define CSR_HPMCOUNTER19 0xc13
+#define CSR_HPMCOUNTER20 0xc14
+#define CSR_HPMCOUNTER21 0xc15
+#define CSR_HPMCOUNTER22 0xc16
+#define CSR_HPMCOUNTER23 0xc17
+#define CSR_HPMCOUNTER24 0xc18
+#define CSR_HPMCOUNTER25 0xc19
+#define CSR_HPMCOUNTER26 0xc1a
+#define CSR_HPMCOUNTER27 0xc1b
+#define CSR_HPMCOUNTER28 0xc1c
+#define CSR_HPMCOUNTER29 0xc1d
+#define CSR_HPMCOUNTER30 0xc1e
+#define CSR_HPMCOUNTER31 0xc1f
+#define CSR_SSTATUS 0x100
+#define CSR_SIE 0x104
+#define CSR_STVEC 0x105
+#define CSR_SCOUNTEREN 0x106
+#define CSR_SSCRATCH 0x140
+#define CSR_SEPC 0x141
+#define CSR_SCAUSE 0x142
+#define CSR_SBADADDR 0x143
+#define CSR_SIP 0x144
+#define CSR_SPTBR 0x180
+#define CSR_SATP 0x180
+#define CSR_MSTATUS 0x300
+#define CSR_MISA 0x301
+#define CSR_MEDELEG 0x302
+#define CSR_MIDELEG 0x303
+#define CSR_MIE 0x304
+#define CSR_MTVEC 0x305
+#define CSR_MCOUNTEREN 0x306
+#define CSR_MSCRATCH 0x340
+#define CSR_MEPC 0x341
+#define CSR_MCAUSE 0x342
+#define CSR_MBADADDR 0x343
+#define CSR_MIP 0x344
+#define CSR_PMPCFG0 0x3a0
+#define CSR_PMPCFG1 0x3a1
+#define CSR_PMPCFG2 0x3a2
+#define CSR_PMPCFG3 0x3a3
+#define CSR_PMPADDR0 0x3b0
+#define CSR_PMPADDR1 0x3b1
+#define CSR_PMPADDR2 0x3b2
+#define CSR_PMPADDR3 0x3b3
+#define CSR_PMPADDR4 0x3b4
+#define CSR_PMPADDR5 0x3b5
+#define CSR_PMPADDR6 0x3b6
+#define CSR_PMPADDR7 0x3b7
+#define CSR_PMPADDR8 0x3b8
+#define CSR_PMPADDR9 0x3b9
+#define CSR_PMPADDR10 0x3ba
+#define CSR_PMPADDR11 0x3bb
+#define CSR_PMPADDR12 0x3bc
+#define CSR_PMPADDR13 0x3bd
+#define CSR_PMPADDR14 0x3be
+#define CSR_PMPADDR15 0x3bf
+#define CSR_TSELECT 0x7a0
+#define CSR_TDATA1 0x7a1
+#define CSR_TDATA2 0x7a2
+#define CSR_TDATA3 0x7a3
+#define CSR_DCSR 0x7b0
+#define CSR_DPC 0x7b1
+#define CSR_DSCRATCH 0x7b2
+#define CSR_MCYCLE 0xb00
+#define CSR_MINSTRET 0xb02
+#define CSR_MHPMCOUNTER3 0xb03
+#define CSR_MHPMCOUNTER4 0xb04
+#define CSR_MHPMCOUNTER5 0xb05
+#define CSR_MHPMCOUNTER6 0xb06
+#define CSR_MHPMCOUNTER7 0xb07
+#define CSR_MHPMCOUNTER8 0xb08
+#define CSR_MHPMCOUNTER9 0xb09
+#define CSR_MHPMCOUNTER10 0xb0a
+#define CSR_MHPMCOUNTER11 0xb0b
+#define CSR_MHPMCOUNTER12 0xb0c
+#define CSR_MHPMCOUNTER13 0xb0d
+#define CSR_MHPMCOUNTER14 0xb0e
+#define CSR_MHPMCOUNTER15 0xb0f
+#define CSR_MHPMCOUNTER16 0xb10
+#define CSR_MHPMCOUNTER17 0xb11
+#define CSR_MHPMCOUNTER18 0xb12
+#define CSR_MHPMCOUNTER19 0xb13
+#define CSR_MHPMCOUNTER20 0xb14
+#define CSR_MHPMCOUNTER21 0xb15
+#define CSR_MHPMCOUNTER22 0xb16
+#define CSR_MHPMCOUNTER23 0xb17
+#define CSR_MHPMCOUNTER24 0xb18
+#define CSR_MHPMCOUNTER25 0xb19
+#define CSR_MHPMCOUNTER26 0xb1a
+#define CSR_MHPMCOUNTER27 0xb1b
+#define CSR_MHPMCOUNTER28 0xb1c
+#define CSR_MHPMCOUNTER29 0xb1d
+#define CSR_MHPMCOUNTER30 0xb1e
+#define CSR_MHPMCOUNTER31 0xb1f
+#define CSR_MUCOUNTEREN 0x320
+#define CSR_MSCOUNTEREN 0x321
+#define CSR_MHPMEVENT3 0x323
+#define CSR_MHPMEVENT4 0x324
+#define CSR_MHPMEVENT5 0x325
+#define CSR_MHPMEVENT6 0x326
+#define CSR_MHPMEVENT7 0x327
+#define CSR_MHPMEVENT8 0x328
+#define CSR_MHPMEVENT9 0x329
+#define CSR_MHPMEVENT10 0x32a
+#define CSR_MHPMEVENT11 0x32b
+#define CSR_MHPMEVENT12 0x32c
+#define CSR_MHPMEVENT13 0x32d
+#define CSR_MHPMEVENT14 0x32e
+#define CSR_MHPMEVENT15 0x32f
+#define CSR_MHPMEVENT16 0x330
+#define CSR_MHPMEVENT17 0x331
+#define CSR_MHPMEVENT18 0x332
+#define CSR_MHPMEVENT19 0x333
+#define CSR_MHPMEVENT20 0x334
+#define CSR_MHPMEVENT21 0x335
+#define CSR_MHPMEVENT22 0x336
+#define CSR_MHPMEVENT23 0x337
+#define CSR_MHPMEVENT24 0x338
+#define CSR_MHPMEVENT25 0x339
+#define CSR_MHPMEVENT26 0x33a
+#define CSR_MHPMEVENT27 0x33b
+#define CSR_MHPMEVENT28 0x33c
+#define CSR_MHPMEVENT29 0x33d
+#define CSR_MHPMEVENT30 0x33e
+#define CSR_MHPMEVENT31 0x33f
+#define CSR_MVENDORID 0xf11
+#define CSR_MARCHID 0xf12
+#define CSR_MIMPID 0xf13
+#define CSR_MHARTID 0xf14
+#define CSR_CYCLEH 0xc80
+#define CSR_TIMEH 0xc81
+#define CSR_INSTRETH 0xc82
+#define CSR_HPMCOUNTER3H 0xc83
+#define CSR_HPMCOUNTER4H 0xc84
+#define CSR_HPMCOUNTER5H 0xc85
+#define CSR_HPMCOUNTER6H 0xc86
+#define CSR_HPMCOUNTER7H 0xc87
+#define CSR_HPMCOUNTER8H 0xc88
+#define CSR_HPMCOUNTER9H 0xc89
+#define CSR_HPMCOUNTER10H 0xc8a
+#define CSR_HPMCOUNTER11H 0xc8b
+#define CSR_HPMCOUNTER12H 0xc8c
+#define CSR_HPMCOUNTER13H 0xc8d
+#define CSR_HPMCOUNTER14H 0xc8e
+#define CSR_HPMCOUNTER15H 0xc8f
+#define CSR_HPMCOUNTER16H 0xc90
+#define CSR_HPMCOUNTER17H 0xc91
+#define CSR_HPMCOUNTER18H 0xc92
+#define CSR_HPMCOUNTER19H 0xc93
+#define CSR_HPMCOUNTER20H 0xc94
+#define CSR_HPMCOUNTER21H 0xc95
+#define CSR_HPMCOUNTER22H 0xc96
+#define CSR_HPMCOUNTER23H 0xc97
+#define CSR_HPMCOUNTER24H 0xc98
+#define CSR_HPMCOUNTER25H 0xc99
+#define CSR_HPMCOUNTER26H 0xc9a
+#define CSR_HPMCOUNTER27H 0xc9b
+#define CSR_HPMCOUNTER28H 0xc9c
+#define CSR_HPMCOUNTER29H 0xc9d
+#define CSR_HPMCOUNTER30H 0xc9e
+#define CSR_HPMCOUNTER31H 0xc9f
+#define CSR_MCYCLEH 0xb80
+#define CSR_MINSTRETH 0xb82
+#define CSR_MHPMCOUNTER3H 0xb83
+#define CSR_MHPMCOUNTER4H 0xb84
+#define CSR_MHPMCOUNTER5H 0xb85
+#define CSR_MHPMCOUNTER6H 0xb86
+#define CSR_MHPMCOUNTER7H 0xb87
+#define CSR_MHPMCOUNTER8H 0xb88
+#define CSR_MHPMCOUNTER9H 0xb89
+#define CSR_MHPMCOUNTER10H 0xb8a
+#define CSR_MHPMCOUNTER11H 0xb8b
+#define CSR_MHPMCOUNTER12H 0xb8c
+#define CSR_MHPMCOUNTER13H 0xb8d
+#define CSR_MHPMCOUNTER14H 0xb8e
+#define CSR_MHPMCOUNTER15H 0xb8f
+#define CSR_MHPMCOUNTER16H 0xb90
+#define CSR_MHPMCOUNTER17H 0xb91
+#define CSR_MHPMCOUNTER18H 0xb92
+#define CSR_MHPMCOUNTER19H 0xb93
+#define CSR_MHPMCOUNTER20H 0xb94
+#define CSR_MHPMCOUNTER21H 0xb95
+#define CSR_MHPMCOUNTER22H 0xb96
+#define CSR_MHPMCOUNTER23H 0xb97
+#define CSR_MHPMCOUNTER24H 0xb98
+#define CSR_MHPMCOUNTER25H 0xb99
+#define CSR_MHPMCOUNTER26H 0xb9a
+#define CSR_MHPMCOUNTER27H 0xb9b
+#define CSR_MHPMCOUNTER28H 0xb9c
+#define CSR_MHPMCOUNTER29H 0xb9d
+#define CSR_MHPMCOUNTER30H 0xb9e
+#define CSR_MHPMCOUNTER31H 0xb9f
+
+/* mstatus bits */
+#define MSTATUS_UIE         0x00000001
+#define MSTATUS_SIE         0x00000002
+#define MSTATUS_HIE         0x00000004
+#define MSTATUS_MIE         0x00000008
+#define MSTATUS_UPIE        0x00000010
+#define MSTATUS_SPIE        0x00000020
+#define MSTATUS_HPIE        0x00000040
+#define MSTATUS_MPIE        0x00000080
+#define MSTATUS_SPP         0x00000100
+#define MSTATUS_HPP         0x00000600
+#define MSTATUS_MPP         0x00001800
+#define MSTATUS_FS          0x00006000
+#define MSTATUS_XS          0x00018000
+#define MSTATUS_MPRV        0x00020000
+#define MSTATUS_PUM         0x00040000 /* until: priv-1.9.1 */
+#define MSTATUS_SUM         0x00040000 /* since: priv-1.10 */
+#define MSTATUS_MXR         0x00080000
+#define MSTATUS_VM          0x1F000000 /* until: priv-1.9.1 */
+#define MSTATUS_TVM         0x00100000 /* since: priv-1.10 */
+#define MSTATUS_TW          0x20000000 /* since: priv-1.10 */
+#define MSTATUS_TSR         0x40000000 /* since: priv-1.10 */
+
+#define MSTATUS64_UXL       0x0000000300000000ULL
+#define MSTATUS64_SXL       0x0000000C00000000ULL
+
+#define MSTATUS32_SD        0x80000000
+#define MSTATUS64_SD        0x8000000000000000ULL
+
+#if defined(TARGET_RH850)
+#define MSTATUS_SD MSTATUS32_SD
+#endif
+
+/* sstatus bits */
+#define SSTATUS_UIE         0x00000001
+#define SSTATUS_SIE         0x00000002
+#define SSTATUS_UPIE        0x00000010
+#define SSTATUS_SPIE        0x00000020
+#define SSTATUS_SPP         0x00000100
+#define SSTATUS_FS          0x00006000
+#define SSTATUS_XS          0x00018000
+#define SSTATUS_PUM         0x00040000 /* until: priv-1.9.1 */
+#define SSTATUS_SUM         0x00040000 /* since: priv-1.10 */
+#define SSTATUS_MXR         0x00080000
+
+#define SSTATUS32_SD        0x80000000
+#define SSTATUS64_SD        0x8000000000000000ULL
+
+#if defined(TARGET_RH850)
+#define SSTATUS_SD SSTATUS32_SD
+#endif
+
+/* irqs */
+#define MIP_SSIP            (1 << IRQ_S_SOFT)
+#define MIP_HSIP            (1 << IRQ_H_SOFT)
+#define MIP_MSIP            (1 << IRQ_M_SOFT)
+#define MIP_STIP            (1 << IRQ_S_TIMER)
+#define MIP_HTIP            (1 << IRQ_H_TIMER)
+#define MIP_MTIP            (1 << IRQ_M_TIMER)
+#define MIP_SEIP            (1 << IRQ_S_EXT)
+#define MIP_HEIP            (1 << IRQ_H_EXT)
+#define MIP_MEIP            (1 << IRQ_M_EXT)
+
+#define SIP_SSIP            MIP_SSIP
+#define SIP_STIP            MIP_STIP
+#define SIP_SEIP            MIP_SEIP
+
+#define PRV_U 0
+#define PRV_S 1
+#define PRV_H 2
+#define PRV_M 3
+
+/* privileged ISA 1.9.1 VM modes (mstatus.vm) */
+#define VM_1_09_MBARE 0
+#define VM_1_09_MBB   1
+#define VM_1_09_MBBID 2
+#define VM_1_09_SV32  8
+#define VM_1_09_SV39  9
+#define VM_1_09_SV48  10
+
+/* privileged ISA 1.10.0 VM modes (satp.mode) */
+#define VM_1_10_MBARE 0
+#define VM_1_10_SV32  1
+#define VM_1_10_SV39  8
+#define VM_1_10_SV48  9
+#define VM_1_10_SV57  10
+#define VM_1_10_SV64  11
+
+/* privileged ISA interrupt causes */
+#define IRQ_U_SOFT      0  /* since: priv-1.10 */
+#define IRQ_S_SOFT      1
+#define IRQ_H_SOFT      2  /* until: priv-1.9.1 */
+#define IRQ_M_SOFT      3  /* until: priv-1.9.1 */
+#define IRQ_U_TIMER     4  /* since: priv-1.10 */
+#define IRQ_S_TIMER     5
+#define IRQ_H_TIMER     6  /* until: priv-1.9.1 */
+#define IRQ_M_TIMER     7  /* until: priv-1.9.1 */
+#define IRQ_U_EXT       8  /* since: priv-1.10 */
+#define IRQ_S_EXT       9
+#define IRQ_H_EXT       10 /* until: priv-1.9.1 */
+#define IRQ_M_EXT       11 /* until: priv-1.9.1 */
+#define IRQ_X_COP       12 /* non-standard */
+
+/* Default addresses */
+#define DEFAULT_RSTVEC     0x00000000
+
+/* RV32 satp field masks */
+#define SATP32_MODE 0x80000000
+#define SATP32_ASID 0x7fc00000
+#define SATP32_PPN  0x003fffff
+
+/* RV64 satp field masks */
+#define SATP64_MODE 0xF000000000000000ULL
+#define SATP64_ASID 0x0FFFF00000000000ULL
+#define SATP64_PPN  0x00000FFFFFFFFFFFULL
+
+#if defined(TARGET_RH850)
+#define SATP_MODE SATP32_MODE
+#define SATP_ASID SATP32_ASID
+#define SATP_PPN  SATP32_PPN
+#endif
+
+/* RH850 Exception Codes */
+#define EXCP_NONE                       -1 /* not a real RH850 exception code */
+#define RH850_EXCP_INST_ADDR_MIS           0x0
+#define RH850_EXCP_INST_ACCESS_FAULT       0x1
+#define RH850_EXCP_ILLEGAL_INST            0x2
+#define RH850_EXCP_BREAKPOINT              0x3
+#define RH850_EXCP_LOAD_ADDR_MIS           0x4
+#define RH850_EXCP_LOAD_ACCESS_FAULT       0x5
+#define RH850_EXCP_STORE_AMO_ADDR_MIS      0x6
+#define RH850_EXCP_STORE_AMO_ACCESS_FAULT  0x7
+#define RH850_EXCP_U_ECALL                 0x8 /* for convenience, report all
+                                                  ECALLs as this, handler
+                                                  fixes */
+#define RH850_EXCP_S_ECALL                 0x9
+#define RH850_EXCP_H_ECALL                 0xa
+#define RH850_EXCP_M_ECALL                 0xb
+#define RH850_EXCP_INST_PAGE_FAULT         0xc /* since: priv-1.10.0 */
+#define RH850_EXCP_LOAD_PAGE_FAULT         0xd /* since: priv-1.10.0 */
+#define RH850_EXCP_STORE_PAGE_FAULT        0xf /* since: priv-1.10.0 */
+#define RH850_EXCP_FETRAP                  0x10 
+#define RH850_EXCP_TRAP                    0x11
+#define RH850_EXCP_RIE                     0x12
+#define RH850_EXCP_SYSCALL                 0x13
+#define RH850_EXCP_EIINT                   0x14
+#define RH850_EXCP_FEINT                   0x15
+#define RH850_EXCP_FENMI                   0x16
+
+/* Specific interrupts (FENMI, FEINT, EIINT). */
+#define RH850_INT_FENMI                     CPU_INTERRUPT_TGT_EXT_0  /* Exception handler address is table-based */
+#define RH850_INT_FEINT                     CPU_INTERRUPT_TGT_EXT_1  /* Defines a non-maskable FE interrupt */
+#define RH850_INT_EIINT                     CPU_INTERRUPT_TGT_EXT_2  /* Defines a maskable FE interrupt */
+
+#define RH850_EXCP_INT_FLAG                0x80000000
+#define RH850_EXCP_INT_MASK                0x7fffffff
+
+
+/* page table entry (PTE) fields */
+#define PTE_V     0x001 /* Valid */
+#define PTE_R     0x002 /* Read */
+#define PTE_W     0x004 /* Write */
+#define PTE_X     0x008 /* Execute */
+#define PTE_U     0x010 /* User */
+#define PTE_G     0x020 /* Global */
+#define PTE_A     0x040 /* Accessed */
+#define PTE_D     0x080 /* Dirty */
+#define PTE_SOFT  0x300 /* Reserved for Software */
+
+#define PTE_PPN_SHIFT 10
+
+#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
diff --git a/qemu/target/rh850/cpu_user.h b/qemu/target/rh850/cpu_user.h
new file mode 100644
index 0000000000..c2199610ab
--- /dev/null
+++ b/qemu/target/rh850/cpu_user.h
@@ -0,0 +1,13 @@
+#define xRA 1   /* return address (aka link register) */
+#define xSP 2   /* stack pointer */
+#define xGP 3   /* global pointer */
+#define xTP 4   /* thread pointer */
+
+#define xA0 10  /* gpr[10-17] are syscall arguments */
+#define xA1 11
+#define xA2 12
+#define xA3 13
+#define xA4 14
+#define xA5 15
+#define xA6 16
+#define xA7 17  /* syscall number goes here */
diff --git a/qemu/target/rh850/fpu_helper.c b/qemu/target/rh850/fpu_helper.c
new file mode 100644
index 0000000000..d99c8613dd
--- /dev/null
+++ b/qemu/target/rh850/fpu_helper.c
@@ -0,0 +1,823 @@
+/*
+ * RH850 FPU Emulation Helpers for QEMU.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include <stdlib.h>
+#include "cpu.h"
+#include "qemu/host-utils.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+
+target_ulong cpu_rh850_get_fflags(CPURH850State *env)
+{
+    int soft = get_float_exception_flags(&env->fp_status);
+    target_ulong hard = 0;
+
+    hard |= (soft & float_flag_inexact) ? FPEXC_NX : 0;
+    hard |= (soft & float_flag_underflow) ? FPEXC_UF : 0;
+    hard |= (soft & float_flag_overflow) ? FPEXC_OF : 0;
+    hard |= (soft & float_flag_divbyzero) ? FPEXC_DZ : 0;
+    hard |= (soft & float_flag_invalid) ? FPEXC_NV : 0;
+
+    return hard;
+}
+
+void cpu_rh850_set_fflags(CPURH850State *env, target_ulong hard)
+{
+    int soft = 0;
+
+    soft |= (hard & FPEXC_NX) ? float_flag_inexact : 0;
+    soft |= (hard & FPEXC_UF) ? float_flag_underflow : 0;
+    soft |= (hard & FPEXC_OF) ? float_flag_overflow : 0;
+    soft |= (hard & FPEXC_DZ) ? float_flag_divbyzero : 0;
+    soft |= (hard & FPEXC_NV) ? float_flag_invalid : 0;
+
+    set_float_exception_flags(soft, &env->fp_status);
+}
+
+void helper_set_rounding_mode(CPURH850State *env, uint32_t rm)
+{
+    int softrm;
+
+    if (rm == 7) {
+        rm = 0; //env->frm;
+    }
+    switch (rm) {
+    case 0:
+        softrm = float_round_nearest_even;
+        break;
+    case 1:
+        softrm = float_round_to_zero;
+        break;
+    case 2:
+        softrm = float_round_down;
+        break;
+    case 3:
+        softrm = float_round_up;
+        break;
+    case 4:
+        softrm = float_round_ties_away;
+        break;
+    default:
+        qemu_log_mask(CPU_LOG_INT, "%s\n", __func__);
+        do_raise_exception_err(env, RH850_EXCP_ILLEGAL_INST, GETPC());
+    }
+
+    set_float_rounding_mode(softrm, &env->fp_status);
+}
+
+/* Propagate softfloat flags into FPSR. */
+void helper_f_sync_fflags(CPURH850State *env)
+{
+    target_ulong flags;
+
+    /* Retrieve softfloat flags. */
+    flags = cpu_rh850_get_fflags(env);
+
+    /* Handle inexact flag. */
+    if (flags & FPEXC_NX)
+    {
+        if (env->fpsr & (1 << 5))
+        {
+            /* Inexact exception allowed, set cause bit. */
+            env->fpsr |= (1 << 10);
+        }
+        else
+        {
+            /* Set preservation bit. */
+            flags |= 1 << 0;
+        }
+    }
+
+    /* Handle underflow flag. */
+    if (flags & FPEXC_UF)
+    {
+        if (env->fpsr & (1 << 6))
+        {
+            /* Underflow exception allowed, set cause bit. */
+            env->fpsr |= (1 << 11);
+        }
+        else
+        {
+            /* Set preservation bit. */
+            env->fpsr |= 1 << 1;
+        }
+    }
+
+    /* Handle overflow flag. */
+    if (flags & FPEXC_OF)
+    {
+        if (env->fpsr & (1 << 7))
+        {
+            /* Overflow exception allowed, set cause bit. */
+            env->fpsr |= (1 << 12);
+        }
+        else
+        {
+            /* Set preservation bit. */
+            env->fpsr |= 1 << 2;
+        }
+    }
+
+    /* Handle div-by-zero flag. */
+    if (flags & FPEXC_DZ)
+    {
+        if (env->fpsr & (1 << 8))
+        {
+            /* Div-by-zero exception allowed, set cause bit. */
+            env->fpsr |= (1 << 13);
+        }
+        else
+        {
+            /* Set preservation bit. */
+            env->fpsr |= 1 << 3;
+        }
+    }
+
+    /* Handle invalid flag. */
+    if (flags & FPEXC_NV)
+    {
+        if (env->fpsr & (1 << 9))
+        {
+            /* Div-by-zero exception allowed, set cause bit. */
+            env->fpsr |= (1 << 14);
+        }
+        else
+        {
+            /* Set preservation bit. */
+            env->fpsr |= 1 << 4;
+        }
+    }
+}
+
+/**
+ * FPU flags checks
+ **/
+
+uint32_t HELPER(f32_is_normal)(CPURH850State *env, uint32_t frs1)
+{
+    return (uint32_t)float32_is_normal(frs1);
+}
+
+uint32_t HELPER(f32_is_zero_or_normal)(CPURH850State *env, uint32_t frs1)
+{
+    return (uint32_t)float32_is_zero_or_normal(frs1);
+}
+
+uint32_t HELPER(f32_is_infinity)(CPURH850State *env, uint32_t frs1)
+{
+    return (uint32_t)float32_is_infinity(frs1);
+}
+
+
+
+uint64_t helper_fmadd_s(CPURH850State *env, uint64_t frs1, uint64_t frs2,
+                        uint64_t frs3)
+{
+    return float32_muladd(frs1, frs2, frs3, 0, &env->fp_status);
+}
+
+uint64_t helper_fmadd_d(CPURH850State *env, uint64_t frs1, uint64_t frs2,
+                        uint64_t frs3)
+{
+    return float64_muladd(frs1, frs2, frs3, 0, &env->fp_status);
+}
+
+uint64_t helper_fmsub_s(CPURH850State *env, uint64_t frs1, uint64_t frs2,
+                        uint64_t frs3)
+{
+    return float32_muladd(frs1, frs2, frs3, float_muladd_negate_c,
+                          &env->fp_status);
+}
+
+uint64_t helper_fmsub_d(CPURH850State *env, uint64_t frs1, uint64_t frs2,
+                        uint64_t frs3)
+{
+    return float64_muladd(frs1, frs2, frs3, float_muladd_negate_c,
+                          &env->fp_status);
+}
+
+uint64_t helper_fnmsub_s(CPURH850State *env, uint64_t frs1, uint64_t frs2,
+                         uint64_t frs3)
+{
+    return float32_muladd(frs1, frs2, frs3, float_muladd_negate_product,
+                          &env->fp_status);
+}
+
+uint64_t helper_fnmsub_d(CPURH850State *env, uint64_t frs1, uint64_t frs2,
+                         uint64_t frs3)
+{
+    return float64_muladd(frs1, frs2, frs3, float_muladd_negate_product,
+                          &env->fp_status);
+}
+
+uint64_t helper_fnmadd_s(CPURH850State *env, uint64_t frs1, uint64_t frs2,
+                         uint64_t frs3)
+{
+    return float32_muladd(frs1, frs2, frs3, float_muladd_negate_c |
+                          float_muladd_negate_product, &env->fp_status);
+}
+
+uint64_t helper_fnmadd_d(CPURH850State *env, uint64_t frs1, uint64_t frs2,
+                         uint64_t frs3)
+{
+    return float64_muladd(frs1, frs2, frs3, float_muladd_negate_c |
+                          float_muladd_negate_product, &env->fp_status);
+}
+
+
+/**
+ * Floating-point simple precision helpers.
+ **/
+
+uint32_t HELPER(fadd_s)(CPURH850State *env, uint32_t frs1, uint32_t frs2)
+{
+    return float32_add(frs1, frs2, &env->fp_status);
+}
+
+uint32_t HELPER(fsub_s)(CPURH850State *env, uint32_t frs1, uint32_t frs2)
+{
+    return float32_sub(frs1, frs2, &env->fp_status);
+}
+
+uint32_t HELPER(fmul_s)(CPURH850State *env, uint32_t frs1, uint32_t frs2)
+{
+    return float32_mul(frs1, frs2, &env->fp_status);
+}
+
+uint32_t HELPER(fmax_s)(CPURH850State *env, uint32_t frs1, uint32_t frs2)
+{
+    return float32_maxnum(frs1, frs2, &env->fp_status);
+}
+
+uint32_t HELPER(fmin_s)(CPURH850State *env, uint32_t frs1, uint32_t frs2)
+{
+    return float32_minnum(frs1, frs2, &env->fp_status);
+}
+
+uint32_t HELPER(fdiv_s)(CPURH850State *env, uint32_t frs1, uint32_t frs2)
+{
+    return float32_div(frs1, frs2, &env->fp_status);
+}
+
+uint32_t HELPER(fabs_s)(CPURH850State *env, uint32_t frs1)
+{
+    return float32_abs(frs1);
+}
+
+uint32_t HELPER(fneg_s)(CPURH850State *env, uint32_t frs1)
+{
+    return (frs1^0x80000000);
+}
+
+uint32_t HELPER(ftrnc_sw)(CPURH850State *env, uint32_t frs1)
+{
+    return float32_to_int32_round_to_zero(frs1, &env->fp_status);
+}
+
+uint32_t HELPER(fceil_sw)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert to int32 and round to positive. */
+    return float32_to_int32_scalbn(frs1, float_round_up, 0, &env->fp_status);
+}
+
+uint32_t HELPER(ffloor_sw)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert to int32 and round to positive. */
+    return float32_to_int32_scalbn(frs1, float_round_down, 0, &env->fp_status);
+}
+
+uint32_t HELPER(fcvt_sw)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert to int32 and round based on fp_status. */
+    return float32_to_int32(frs1, &env->fp_status);
+}
+
+uint32_t HELPER(fcvt_ls)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert int64 to float32 and round based on fp_status. */
+    return int64_to_float32(frs1, &env->fp_status);
+}
+
+uint32_t HELPER(fcvt_hs)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert lower half of frs1 into float32. */
+    return int16_to_float32((int16_t)(frs1&0xffff), &env->fp_status);
+}
+
+uint32_t HELPER(fcvt_sh)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert float32 to int16_t, zero-extended. */
+    return float32_to_int16(frs1, &env->fp_status) & 0xffff;
+}
+
+uint32_t HELPER(fcvt_ws)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert to float32 and round based on fp_status. */
+    return int32_to_float32(frs1, &env->fp_status);
+}
+
+uint32_t HELPER(ftrnc_suw)(CPURH850State *env, uint32_t frs1)
+{
+    return float32_to_uint32_round_to_zero(frs1, &env->fp_status);
+}
+
+uint32_t HELPER(fceil_suw)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert to int32 and round to positive. */
+    return float32_to_uint32_scalbn(frs1, float_round_up, 0, &env->fp_status);
+}
+
+uint32_t HELPER(ffloor_suw)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert to int32 and round to positive. */
+    return float32_to_uint32_scalbn(frs1, float_round_down, 0, &env->fp_status);
+}
+
+uint32_t HELPER(fcvt_suw)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert to int32 and round based on fp_status. */
+    return float32_to_uint32(frs1, &env->fp_status);
+}
+
+uint32_t HELPER(fcvt_uws)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert from uint32 to float32 and round based on fp_status. */
+    return uint32_to_float32(frs1, &env->fp_status);
+}
+
+uint32_t HELPER(fcvt_uls)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert uint64 to float32 and round based on fp_status. */
+    return uint64_to_float32(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(ftrnc_sl)(CPURH850State *env, uint32_t frs1)
+{
+    return float32_to_int64_round_to_zero(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(fceil_sl)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert float32 to int64 and round to upper value. */
+    return float32_to_int64_scalbn(frs1, float_round_up, 0, &env->fp_status);
+}
+
+uint64_t HELPER(ffloor_sl)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert float32 to int64 and round to lower value. */
+    return float32_to_int64_scalbn(frs1, float_round_down, 0, &env->fp_status);
+}
+
+uint64_t HELPER(fcvt_sl)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert float32 to int64. */
+    return float32_to_int64(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(ftrnc_sul)(CPURH850State *env, uint32_t frs1)
+{
+    return float32_to_uint64_round_to_zero(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(fceil_sul)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert float32 to uint64 and round to upper value. */
+    return float32_to_uint64_scalbn(frs1, float_round_up, 0, &env->fp_status);
+}
+
+uint64_t HELPER(ffloor_sul)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert float32 to uint64 and round to lower value. */
+    return float32_to_uint64_scalbn(frs1, float_round_down, 0, &env->fp_status);
+}
+
+uint64_t HELPER(fcvt_sul)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert float32 to uint64. */
+    return float32_to_uint64(frs1, &env->fp_status);
+}
+
+uint32_t HELPER(fsqrt_s)(CPURH850State *env, uint32_t frs1)
+{
+    return float32_sqrt(frs1, &env->fp_status);
+}
+
+uint32_t HELPER(frecip_s)(CPURH850State *env, uint32_t frs1)
+{
+    /* Compute 1/x (0x3f800000 = float32(1.1)). */
+    return float32_div(0x3f800000, frs1, &env->fp_status);
+}
+
+uint32_t HELPER(frsqrt_s)(CPURH850State *env, uint32_t frs1)
+{
+    /* Compute 1/sqrt(x). */
+    return HELPER(frecip_s)(env, float32_sqrt(frs1, &env->fp_status));
+}
+
+uint32_t HELPER(f_is_nan_s)(CPURH850State *env, uint32_t frs1)
+{
+    /* Check if float32 is NaN. */
+    return float32_is_any_nan(frs1);
+}
+
+uint32_t helper_fle_s(CPURH850State *env, uint32_t frs1, uint32_t frs2)
+{
+    return float32_le(frs1, frs2, &env->fp_status);
+}
+
+uint32_t helper_flt_s(CPURH850State *env, uint32_t frs1, uint32_t frs2)
+{
+    return float32_lt(frs1, frs2, &env->fp_status);
+}
+
+uint32_t helper_feq_s(CPURH850State *env, uint32_t frs1, uint32_t frs2)
+{
+    return float32_eq_quiet(frs1, frs2, &env->fp_status);
+}
+
+
+uint32_t HELPER(fmaf_s)(CPURH850State *env, uint32_t frs1, uint32_t frs2, uint32_t frs3)
+{
+    /* Compute (frs1 * frs2) + frs3 */
+    return float32_muladd(frs1, frs2, frs3, 0, &env->fp_status);
+}
+
+uint32_t HELPER(fmsf_s)(CPURH850State *env, uint32_t frs1, uint32_t frs2, uint32_t frs3)
+{
+    /* Compute (frs1 * frs2) - frs3 */
+    return float32_muladd(frs1, frs2, frs3, float_muladd_negate_c, &env->fp_status);
+}
+
+uint32_t HELPER(fnmaf_s)(CPURH850State *env, uint32_t frs1, uint32_t frs2, uint32_t frs3)
+{
+    /* Compute (frs1 * frs2) + frs3 */
+    return float32_muladd(frs1, frs2, frs3, float_muladd_negate_result, &env->fp_status);
+}
+
+uint32_t HELPER(fnmsf_s)(CPURH850State *env, uint32_t frs1, uint32_t frs2, uint32_t frs3)
+{
+    /* Compute (frs1 * frs2) - frs3 */
+    return float32_muladd(frs1, frs2, frs3, float_muladd_negate_c | float_muladd_negate_result, &env->fp_status);
+}
+
+
+
+target_ulong helper_fcvt_w_s(CPURH850State *env, uint64_t frs1)
+{
+    return float32_to_int32(frs1, &env->fp_status);
+}
+
+target_ulong helper_fcvt_wu_s(CPURH850State *env, uint64_t frs1)
+{
+    return (int32_t)float32_to_uint32(frs1, &env->fp_status);
+}
+
+#if defined(TARGET_RH85064)
+uint64_t helper_fcvt_l_s(CPURH850State *env, uint64_t frs1)
+{
+    return float32_to_int64(frs1, &env->fp_status);
+}
+
+uint64_t helper_fcvt_lu_s(CPURH850State *env, uint64_t frs1)
+{
+    return float32_to_uint64(frs1, &env->fp_status);
+}
+#endif
+
+uint64_t helper_fcvt_s_w(CPURH850State *env, target_ulong rs1)
+{
+    return int32_to_float32((int32_t)rs1, &env->fp_status);
+}
+
+uint64_t helper_fcvt_s_wu(CPURH850State *env, target_ulong rs1)
+{
+    return uint32_to_float32((uint32_t)rs1, &env->fp_status);
+}
+
+#if defined(TARGET_RH85064)
+uint64_t helper_fcvt_s_l(CPURH850State *env, uint64_t rs1)
+{
+    return int64_to_float32(rs1, &env->fp_status);
+}
+
+uint64_t helper_fcvt_s_lu(CPURH850State *env, uint64_t rs1)
+{
+    return uint64_to_float32(rs1, &env->fp_status);
+}
+#endif
+
+target_ulong helper_fclass_s(uint64_t frs1)
+{
+    float32 f = frs1;
+    bool sign = float32_is_neg(f);
+
+    if (float32_is_infinity(f)) {
+        return sign ? 1 << 0 : 1 << 7;
+    } else if (float32_is_zero(f)) {
+        return sign ? 1 << 3 : 1 << 4;
+    } else if (float32_is_zero_or_denormal(f)) {
+        return sign ? 1 << 2 : 1 << 5;
+    } else if (float32_is_any_nan(f)) {
+        float_status s = { 0 }; /* for snan_bit_is_one */
+        return float32_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
+    } else {
+        return sign ? 1 << 1 : 1 << 6;
+    }
+}
+
+/**
+ * Floating-point double precision helpers.
+ **/
+
+uint64_t HELPER(fadd_d)(CPURH850State *env, uint64_t frs1, uint64_t frs2)
+{
+    return float64_add(frs1, frs2, &env->fp_status);
+}
+
+uint64_t HELPER(fsub_d)(CPURH850State *env, uint64_t frs1, uint64_t frs2)
+{
+    return float64_sub(frs1, frs2, &env->fp_status);
+}
+
+uint64_t HELPER(fmul_d)(CPURH850State *env, uint64_t frs1, uint64_t frs2)
+{
+    return float64_mul(frs1, frs2, &env->fp_status);
+}
+
+uint64_t HELPER(fmax_d)(CPURH850State *env, uint64_t frs1, uint64_t frs2)
+{
+    return float64_maxnum(frs1, frs2, &env->fp_status);
+}
+
+uint64_t HELPER(fmin_d)(CPURH850State *env, uint64_t frs1, uint64_t frs2)
+{
+    return float64_minnum(frs1, frs2, &env->fp_status);
+}
+
+uint64_t HELPER(fdiv_d)(CPURH850State *env, uint64_t frs1, uint64_t frs2)
+{
+    return float64_div(frs1, frs2, &env->fp_status);
+}
+
+uint64_t HELPER(fabs_d)(CPURH850State *env, uint64_t frs1)
+{
+    return float64_abs(frs1);
+}
+
+uint64_t HELPER(fneg_d)(CPURH850State *env, uint64_t frs1)
+{
+    return (frs1 ^ 0x8000000000000000);
+}
+
+uint32_t HELPER(ftrnc_dw)(CPURH850State *env, uint64_t frs1)
+{
+    return float64_to_int32_round_to_zero(frs1, &env->fp_status);
+}
+
+uint32_t HELPER(fceil_dw)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert float64 to int32 and round to upper value. */
+    return float64_to_int32_scalbn(frs1, float_round_up, 0, &env->fp_status);
+}
+
+uint32_t HELPER(ffloor_dw)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert float64 to int32 and round to lower value. */
+    return float64_to_int32_scalbn(frs1, float_round_down, 0, &env->fp_status);
+}
+
+uint32_t HELPER(fcvt_dw)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert float64 to int32. */
+    return float64_to_int32(frs1, &env->fp_status);
+}
+
+uint32_t HELPER(ftrnc_duw)(CPURH850State *env, uint64_t frs1)
+{
+    return float64_to_uint32_round_to_zero(frs1, &env->fp_status);
+}
+
+uint32_t HELPER(fceil_duw)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert float64 to uint32 and round to upper value. */
+    return float64_to_uint32_scalbn(frs1, float_round_up, 0, &env->fp_status);
+}
+
+uint32_t HELPER(ffloor_duw)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert float64 to uint32 and round to lower value. */
+    return float64_to_uint32_scalbn(frs1, float_round_down, 0, &env->fp_status);
+}
+
+uint32_t HELPER(fcvt_duw)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert float64 to uint32. */
+    return float64_to_uint32(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(fcvt_wd)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert int32 to float64. */
+    return int32_to_float64(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(fcvt_ld)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert int32 to float64. */
+    return int64_to_float64(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(fcvt_sd)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert float32 to float64. */
+    return float32_to_float64(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(fcvt_uwd)(CPURH850State *env, uint32_t frs1)
+{
+    /* Convert int32 to float64. */
+    return uint32_to_float64(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(fcvt_uld)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert int32 to float64. */
+    return uint64_to_float64(frs1, &env->fp_status);
+}
+
+
+
+uint64_t HELPER(ftrnc_dl)(CPURH850State *env, uint64_t frs1)
+{
+    return float64_to_int64_round_to_zero(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(fceil_dl)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert float64 to int64 and round to upper value. */
+    return float64_to_int64_scalbn(frs1, float_round_up, 0, &env->fp_status);
+}
+
+uint64_t HELPER(ffloor_dl)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert float64 to int64 and round to lower value. */
+    return float64_to_int64_scalbn(frs1, float_round_down, 0, &env->fp_status);
+}
+
+uint64_t HELPER(fcvt_dl)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert float64 to int64. */
+    return float64_to_int64(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(ftrnc_dul)(CPURH850State *env, uint64_t frs1)
+{
+    return float64_to_uint64_round_to_zero(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(fceil_dul)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert float64 to uint64 and round to upper value. */
+    return float64_to_uint64_scalbn(frs1, float_round_up, 0, &env->fp_status);
+}
+
+uint64_t HELPER(ffloor_dul)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert float64 to uint64 and round to lower value. */
+    return float64_to_uint64_scalbn(frs1, float_round_down, 0, &env->fp_status);
+}
+
+uint64_t HELPER(fcvt_dul)(CPURH850State *env, uint64_t frs1)
+{
+    /* Convert float64 to uint64. */
+    return float64_to_uint64(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(fsqrt_d)(CPURH850State *env, uint64_t frs1)
+{
+    return float64_sqrt(frs1, &env->fp_status);
+}
+
+uint64_t HELPER(frecip_d)(CPURH850State *env, uint64_t frs1)
+{
+    /* Compute 1/x (0x3ff0000000000000 = float64(1.1)). */
+    return float64_div(0x3ff0000000000000, frs1, &env->fp_status);
+}
+
+uint64_t HELPER(frsqrt_d)(CPURH850State *env, uint64_t frs1)
+{
+    /* Compute 1/sqrt(x). */
+    return HELPER(frecip_d)(env, float64_sqrt(frs1, &env->fp_status));
+}
+
+uint32_t HELPER(f_is_nan_d)(CPURH850State *env, uint64_t frs1)
+{
+    /* Check if float64 is NaN. */
+    return float64_is_any_nan(frs1);
+}
+
+
+
+uint64_t helper_fcvt_s_d(CPURH850State *env, uint64_t rs1)
+{
+    return float64_to_float32(rs1, &env->fp_status);
+}
+
+uint64_t helper_fcvt_d_s(CPURH850State *env, uint64_t rs1)
+{
+    return float32_to_float64(rs1, &env->fp_status);
+}
+
+uint32_t helper_fle_d(CPURH850State *env, uint64_t frs1, uint64_t frs2)
+{
+    return float64_le(frs1, frs2, &env->fp_status);
+}
+
+uint32_t helper_flt_d(CPURH850State *env, uint64_t frs1, uint64_t frs2)
+{
+    return float64_lt(frs1, frs2, &env->fp_status);
+}
+
+uint32_t helper_feq_d(CPURH850State *env, uint64_t frs1, uint64_t frs2)
+{
+    return float64_eq_quiet(frs1, frs2, &env->fp_status);
+}
+
+target_ulong helper_fcvt_w_d(CPURH850State *env, uint64_t frs1)
+{
+    return float64_to_int32(frs1, &env->fp_status);
+}
+
+target_ulong helper_fcvt_wu_d(CPURH850State *env, uint64_t frs1)
+{
+    return (int32_t)float64_to_uint32(frs1, &env->fp_status);
+}
+
+#if defined(TARGET_RH85064)
+uint64_t helper_fcvt_l_d(CPURH850State *env, uint64_t frs1)
+{
+    return float64_to_int64(frs1, &env->fp_status);
+}
+
+uint64_t helper_fcvt_lu_d(CPURH850State *env, uint64_t frs1)
+{
+    return float64_to_uint64(frs1, &env->fp_status);
+}
+#endif
+
+uint64_t helper_fcvt_d_w(CPURH850State *env, target_ulong rs1)
+{
+    return int32_to_float64((int32_t)rs1, &env->fp_status);
+}
+
+uint64_t helper_fcvt_d_wu(CPURH850State *env, target_ulong rs1)
+{
+    return uint32_to_float64((uint32_t)rs1, &env->fp_status);
+}
+
+#if defined(TARGET_RH85064)
+uint64_t helper_fcvt_d_l(CPURH850State *env, uint64_t rs1)
+{
+    return int64_to_float64(rs1, &env->fp_status);
+}
+
+uint64_t helper_fcvt_d_lu(CPURH850State *env, uint64_t rs1)
+{
+    return uint64_to_float64(rs1, &env->fp_status);
+}
+#endif
+
+target_ulong helper_fclass_d(uint64_t frs1)
+{
+    float64 f = frs1;
+    bool sign = float64_is_neg(f);
+
+    if (float64_is_infinity(f)) {
+        return sign ? 1 << 0 : 1 << 7;
+    } else if (float64_is_zero(f)) {
+        return sign ? 1 << 3 : 1 << 4;
+    } else if (float64_is_zero_or_denormal(f)) {
+        return sign ? 1 << 2 : 1 << 5;
+    } else if (float64_is_any_nan(f)) {
+        float_status s = { 0 }; /* for snan_bit_is_one */
+        return float64_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
+    } else {
+        return sign ? 1 << 1 : 1 << 6;
+    }
+}
diff --git a/qemu/target/rh850/fpu_translate.c b/qemu/target/rh850/fpu_translate.c
new file mode 100644
index 0000000000..2fd008177b
--- /dev/null
+++ b/qemu/target/rh850/fpu_translate.c
@@ -0,0 +1,1557 @@
+#include "fpu_translate.h"
+#include "instmap.h"
+
+extern TCGv_i32 cpu_ZF;
+
+/* Helpers */
+void fpu_load_i64(TCGContext *tcg_ctx, TCGv_i64 dst, int reg_n);
+void fpu_load_i64_2(TCGContext *tcg_ctx, TCGv_i64 dst0, TCGv_i64 dst1, int reg_n0, int reg_n1);
+void fpu_store_i64(TCGContext *tcg_ctx, int reg_n, TCGv_i64 src);
+
+/* Single-precision */
+void fpu_gen_sp_ir_3(CPURH850State *env, DisasContext *ctx, int operands, int op, int rs1, int rs2, int rs3);
+void fpu_gen_sp_ir_2(CPURH850State *env, DisasContext *ctx, int operands, int op, int rs2, int rs3);
+void fpu_gen_cmpf_s(CPURH850State *env, DisasContext *ctx, int rs1, int rs2, int fcond, int fcbit);
+void fpu_gen_cmov_s(CPURH850State *env, DisasContext *ctx, int rs1, int rs2, int rs3, int fcbit);
+void fpu_gen_trfsr(CPURH850State *env, DisasContext *ctx, int fcbit);
+void fpu_gen_cat1_ir(CPURH850State *env, DisasContext *ctx, int op, int frs1, int frs2, int frs3);
+
+
+/* Double precision */
+void fpu_gen_cmpf_d(CPURH850State *env, DisasContext *ctx, int rs1, int rs2, int fcond, int fcbit);
+void fpu_gen_cmov_d(CPURH850State *env, DisasContext *ctx, int rs1, int rs2, int rs3, int fcbit);
+void fpu_gen_dp_ir_3(CPURH850State *env, DisasContext *ctx, int operands, int op, int rs1, int rs2, int rs3);
+void fpu_gen_dp_ir_2(CPURH850State *env, DisasContext *ctx, int operands, int op, int rs2, int rs3);
+
+
+/**
+ * Helpers for 64-bit register load/store
+ **/
+
+void fpu_load_i64(TCGContext *tcg_ctx, TCGv_i64 dst, int reg_n)
+{
+    TCGv_i32 rl = tcg_temp_local_new_i32(tcg_ctx);
+    TCGv_i32 rh = tcg_temp_local_new_i32(tcg_ctx);
+
+    /* Read float64 from (reg_n/reg_n+1). */
+    gen_get_gpr(tcg_ctx, rl, reg_n);
+    gen_get_gpr(tcg_ctx, rh, reg_n+1);
+    tcg_gen_concat_i32_i64(tcg_ctx, dst, rl, rh);
+
+    /* Free temporary variables. */
+    tcg_temp_free_i32(tcg_ctx, rl);
+    tcg_temp_free_i32(tcg_ctx, rh);
+}
+
+void fpu_store_i64(TCGContext *tcg_ctx, int reg_n, TCGv_i64 src)
+{
+    TCGv_i32 rl = tcg_temp_local_new_i32(tcg_ctx);
+    TCGv_i32 rh = tcg_temp_local_new_i32(tcg_ctx);
+    TCGv_i64 shift = tcg_temp_local_new_i64(tcg_ctx);
+
+    tcg_gen_movi_i64(tcg_ctx, shift, 32);
+    tcg_gen_extrl_i64_i32(tcg_ctx, rl, src);
+    tcg_gen_shr_i64(tcg_ctx, src, src, shift);
+    tcg_gen_extrl_i64_i32(tcg_ctx, rh, src);
+    gen_set_gpr(tcg_ctx, reg_n, rl);
+    gen_set_gpr(tcg_ctx, reg_n + 1, rh);
+
+    /* Free temporary variables. */
+    tcg_temp_free_i32(tcg_ctx, rl);
+    tcg_temp_free_i32(tcg_ctx, rh);
+}
+
+void fpu_load_i64_2(TCGContext *tcg_ctx, TCGv_i64 dst0, TCGv_i64 dst1, int reg_n0, int reg_n1)
+{
+    TCGv_i32 rl = tcg_temp_local_new_i32(tcg_ctx);
+    TCGv_i32 rh = tcg_temp_local_new_i32(tcg_ctx);
+
+    /* Read float64 from (reg_n0/reg_n0 + 1). */
+    gen_get_gpr(tcg_ctx, rl, reg_n0);
+    gen_get_gpr(tcg_ctx, rh, reg_n0 + 1);
+    tcg_gen_concat_i32_i64(tcg_ctx, dst0, rl, rh);
+
+    /* Read float64 from (reg_n1/reg_n1 + 1). */
+    gen_get_gpr(tcg_ctx, rl, reg_n1);
+    gen_get_gpr(tcg_ctx, rh, reg_n1 + 1);
+    tcg_gen_concat_i32_i64(tcg_ctx, dst1, rl, rh);
+
+    /* Free temporary variables. */
+    tcg_temp_free_i32(tcg_ctx, rl);
+    tcg_temp_free_i32(tcg_ctx, rh);
+}
+
+/**
+ * Floating-point simple-precision IR generators.
+ **/
+
+void fpu_gen_cat1_ir(CPURH850State *env, DisasContext *ctx, int op, int frs1, int frs2, int frs3)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+    TCGv r1 = tcg_temp_local_new(tcg_ctx);
+    TCGv r2 = tcg_temp_local_new(tcg_ctx);
+    TCGv r3 = tcg_temp_local_new(tcg_ctx);
+
+    /* Load register content from frs1, frs2 and frs3. */
+    gen_get_gpr(tcg_ctx, r1, frs1);
+    gen_get_gpr(tcg_ctx, r2, frs2);
+    gen_get_gpr(tcg_ctx, r3, frs3);
+
+    switch(op)
+    {
+        case OPC_RH850_FPU_FMAF_S:
+            gen_helper_fmaf_s(tcg_ctx, r3, tcg_ctx->cpu_env, r1, r2, r3);
+            break;
+
+        case OPC_RH850_FPU_FMSF_S:
+            gen_helper_fmsf_s(tcg_ctx, r3, tcg_ctx->cpu_env, r1, r2, r3);
+            break;
+        
+        case OPC_RH850_FPU_FNMAF_S:
+            gen_helper_fnmaf_s(tcg_ctx, r3, tcg_ctx->cpu_env, r1, r2, r3);
+            break;
+
+        case OPC_RH850_FPU_FNMSF_S:
+            gen_helper_fnmsf_s(tcg_ctx, r3, tcg_ctx->cpu_env, r1, r2, r3);
+            break;
+
+        default:
+            /* Unknown instruction. */
+            break;
+    }
+
+    /* Store r3 register into frs3. */
+    gen_set_gpr(tcg_ctx, frs3, r3);
+
+    /* Free locals. */
+    tcg_temp_free(tcg_ctx, r1);
+    tcg_temp_free(tcg_ctx, r2);
+    tcg_temp_free(tcg_ctx, r3);
+}
+
+
+void fpu_gen_sp_ir_2(CPURH850State *env, DisasContext *ctx, int operands, int op, int rs2, int rs3)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+    /* rs1, rs2 and rs3 for TCG */
+	TCGv r2 = tcg_temp_local_new_i32(tcg_ctx);
+    TCGv r3 = tcg_temp_local_new_i32(tcg_ctx);
+    TCGv_i64 r3_64 = tcg_temp_local_new_i64(tcg_ctx);
+
+    /* Load contents from registers. */
+    switch(operands)
+    {
+        case FPU_TYPE_S:
+            {
+                /* Extract value of reg1 and reg2. */
+                gen_get_gpr(tcg_ctx, r2, rs2);
+	
+                /* Apply operation. */
+                switch(op)
+                {
+                    case FPU_OP_ABS:
+                        gen_helper_fabs_s(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_NEG:
+                        gen_helper_fneg_s(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_SQRT:
+                        gen_helper_fsqrt_s(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_RECIP:
+                        gen_helper_frecip_s(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_RSQRT:
+                        gen_helper_frsqrt_s(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+                }
+
+                /* Store result. */
+                gen_set_gpr(tcg_ctx, rs3, r3);
+            }
+            break;
+
+        case FPU_TYPE_SL:
+            {
+                /* Load simple-precision float. */
+                gen_get_gpr(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                switch(op)
+                {
+                    case FPU_OP_TRNC:
+                        gen_helper_ftrnc_sl(tcg_ctx, r3_64, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CEIL:
+                        gen_helper_fceil_sl(tcg_ctx, r3_64, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_FLOOR:
+                        gen_helper_ffloor_sl(tcg_ctx, r3_64, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CVT:
+                        gen_helper_fcvt_sl(tcg_ctx, r3_64, tcg_ctx->cpu_env, r2);
+                        break;
+                }
+
+                /* Store result as long. */
+                fpu_store_i64(tcg_ctx, rs3, r3_64);
+            }
+            break;
+
+        case FPU_TYPE_SUL:
+            {
+                /* Load simple-precision float. */
+                gen_get_gpr(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                switch(op)
+                {
+                    case FPU_OP_TRNC:
+                        gen_helper_ftrnc_sul(tcg_ctx, r3_64, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CEIL:
+                        gen_helper_fceil_sul(tcg_ctx, r3_64, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_FLOOR:
+                        gen_helper_ffloor_sul(tcg_ctx, r3_64, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CVT:
+                        gen_helper_fcvt_sul(tcg_ctx, r3_64, tcg_ctx->cpu_env, r2);
+                        break;
+                }
+
+                /* Store result as long. */
+                fpu_store_i64(tcg_ctx, rs3, r3_64);
+            }
+            break;
+
+
+        case FPU_TYPE_SW:
+            {
+                /* Extract value of reg1 and reg2. */
+                gen_get_gpr(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                switch(op)
+                {
+                    case FPU_OP_TRNC:
+                        gen_helper_ftrnc_sw(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CEIL:
+                        gen_helper_fceil_sw(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_FLOOR:
+                        gen_helper_ffloor_sw(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CVT:
+                        gen_helper_fcvt_sw(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+                }
+
+                /* Store result. */
+                gen_set_gpr(tcg_ctx, rs3, r3);
+            }
+            break;
+
+        case FPU_TYPE_SUW:
+            {
+                /* Extract value of reg1 and reg2. */
+                gen_get_gpr(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                switch(op)
+                {
+                    case FPU_OP_TRNC:
+                        gen_helper_ftrnc_suw(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CEIL:
+                        gen_helper_fceil_suw(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_FLOOR:
+                        gen_helper_ffloor_suw(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CVT:
+                        gen_helper_fcvt_suw(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+                }
+
+                /* Store result. */
+                gen_set_gpr(tcg_ctx, rs3, r3);
+            }
+            break;
+
+        case FPU_TYPE_LS:
+            {
+                /* Load content from register. */
+                fpu_load_i64(tcg_ctx, r3_64, rs2);
+
+                /* Apply operation. */
+                if (op == FPU_OP_CVT)
+                {
+                    gen_helper_fcvt_ls(tcg_ctx, r3, tcg_ctx->cpu_env, r3_64);
+                }
+                else
+                {
+                    /* Unsupported operation. */
+                }
+
+                /* Store result into rs3. */
+                gen_set_gpr(tcg_ctx, rs3, r3);
+            }
+            break;
+
+        case FPU_TYPE_HS:
+            {
+                /* Extract value of reg1 and reg2. */
+                gen_get_gpr(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                if (op == FPU_OP_CVT)
+                {
+                    gen_helper_fcvt_hs(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                }
+                else
+                {
+                    /* Unsupported operation. */
+                }
+
+                /* Store result into rs3. */
+                gen_set_gpr(tcg_ctx, rs3, r3);
+            }
+            break;
+
+        case FPU_TYPE_WS:
+            {
+                /* Extract value of reg1 and reg2. */
+                gen_get_gpr(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                if (op == FPU_OP_CVT)
+                {
+                    gen_helper_fcvt_ws(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                }
+                else
+                {
+                    /* Unsupported operation. */
+                }
+
+                /* Store result into rs3. */
+                gen_set_gpr(tcg_ctx, rs3, r3);
+            }
+            break;
+
+
+        case FPU_TYPE_SH:
+            {
+                /* Extract value of reg1 and reg2. */
+                gen_get_gpr(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                if (op == FPU_OP_CVT)
+                {
+                    gen_helper_fcvt_sh(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                }
+                else
+                {
+                    /* Unsupported operation. */
+                }
+
+                /* Store result into rs3. */
+                gen_set_gpr(tcg_ctx, rs3, r3);
+            }
+            break;
+
+        case FPU_TYPE_ULS:
+            {
+                /* Load content from register. */
+                fpu_load_i64(tcg_ctx, r3_64, rs2);
+
+                /* Apply operation. */
+                if (op == FPU_OP_CVT)
+                {
+                    gen_helper_fcvt_uls(tcg_ctx, r3, tcg_ctx->cpu_env, r3_64);
+                }
+                else
+                {
+                    /* Unsupported operation. */
+                }
+
+                /* Store result into rs3. */
+                gen_set_gpr(tcg_ctx, rs3, r3);
+            }
+            break;
+
+        case FPU_TYPE_UWS:
+            {
+                /* Extract value of reg1 and reg2. */
+                gen_get_gpr(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                if (op == FPU_OP_CVT)
+                {
+                    gen_helper_fcvt_uws(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                }
+                else
+                {
+                    /* Unsupported operation. */
+                }
+
+                /* Store result into rs3. */
+                gen_set_gpr(tcg_ctx, rs3, r3);
+            }
+            break;
+        
+    }
+
+    /* Mov softfloat flags into our register. */
+    gen_helper_f_sync_fflags(tcg_ctx, tcg_ctx->cpu_env);
+
+    /* Free temp. */
+    tcg_temp_free(tcg_ctx, r2);
+    tcg_temp_free(tcg_ctx, r3);
+    tcg_temp_free_i64(tcg_ctx, r3_64);
+}
+
+/**
+ * refactored
+ **/
+
+void fpu_gen_sp_ir_3(CPURH850State *env, DisasContext *ctx, int operands, int op, int rs1, int rs2, int rs3)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+    /* rs1, rs2 and rs3 for TCG */
+    TCGv r1 = tcg_temp_local_new_i32(tcg_ctx);
+	TCGv r2 = tcg_temp_local_new_i32(tcg_ctx);
+    TCGv r3 = tcg_temp_local_new_i32(tcg_ctx);
+
+    /* Load contents from registers. */
+    switch(operands)
+    {
+        case FPU_TYPE_S:
+            {
+                /* Extract value of reg1 and reg2. */
+                gen_get_gpr(tcg_ctx, r1, rs1);
+                gen_get_gpr(tcg_ctx, r2, rs2);
+            }
+            break;
+    }
+
+    /* Apply operation. */
+    switch(op)
+    {
+        case FPU_OP_ADD:
+            gen_helper_fadd_s(tcg_ctx, r3, tcg_ctx->cpu_env, r1, r2);
+            break;
+
+        case FPU_OP_DIV:
+            gen_helper_fdiv_s(tcg_ctx, r3, tcg_ctx->cpu_env, r2, r1);
+            break;
+
+        case FPU_OP_SUB:
+            gen_helper_fsub_s(tcg_ctx, r3, tcg_ctx->cpu_env, r2, r1);
+            break;
+
+        case FPU_OP_MAX:
+            gen_helper_fmax_s(tcg_ctx, r3, tcg_ctx->cpu_env, r1, r2);
+            break;
+
+        case FPU_OP_MIN:
+            gen_helper_fmin_s(tcg_ctx, r3, tcg_ctx->cpu_env, r1, r2);
+            break;
+
+        case FPU_OP_MUL:
+            gen_helper_fmul_s(tcg_ctx, r3, tcg_ctx->cpu_env, r1, r2);
+            break;
+    }
+
+    /* Store result. */
+    switch(operands)
+    {
+        case FPU_TYPE_S:
+            {
+                /* Set reg3. */
+                gen_set_gpr(tcg_ctx, rs3, r3);
+            }
+            break;
+    }
+
+    /* Mov softfloat flags into our register. */
+    gen_helper_f_sync_fflags(tcg_ctx, tcg_ctx->cpu_env);
+
+    /* Free temp. */
+    tcg_temp_free(tcg_ctx, r1);
+    tcg_temp_free(tcg_ctx, r2);
+    tcg_temp_free(tcg_ctx, r3);
+}
+
+
+void fpu_gen_trfsr(CPURH850State *env, DisasContext *ctx, int fcbit)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+    TCGv fpsr = tcg_temp_local_new(tcg_ctx);
+    TCGv mask = tcg_temp_local_new(tcg_ctx);
+    TCGv shift = tcg_temp_local_new(tcg_ctx);
+    TCGv one = tcg_const_i32(tcg_ctx, 1);
+    TCGv value = tcg_temp_local_new(tcg_ctx);
+
+    /* Load fpsr and compute mask. */
+    gen_get_spr(tcg_ctx, BANK_ID_BASIC_0, FPSR_IDX, fpsr);
+    tcg_gen_movi_i32(tcg_ctx, shift, 24 + fcbit);
+    tcg_gen_shl_i32(tcg_ctx, mask, one, shift);
+    
+    /* Extract CCn bit. */
+    tcg_gen_and_i32(tcg_ctx, value, fpsr, mask);
+    tcg_gen_shr_i32(tcg_ctx, value, value, shift);
+
+    /* Set Z flag. */
+    tcg_gen_mov_i32(tcg_ctx, cpu_ZF, value);
+    gen_set_gpr(tcg_ctx, 1, value);
+
+    /* Free locals. */
+    tcg_temp_free(tcg_ctx, fpsr);
+    tcg_temp_free(tcg_ctx, mask);
+    tcg_temp_free(tcg_ctx, shift);
+    tcg_temp_free(tcg_ctx, one);
+    tcg_temp_free(tcg_ctx, value);
+}
+
+void fpu_gen_cmov_s(CPURH850State *env, DisasContext *ctx, int rs1, int rs2, int rs3, int fcbit)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+    TCGLabel *end, *otherwise;
+    TCGv r1 = tcg_temp_local_new(tcg_ctx);
+	TCGv r2 = tcg_temp_local_new(tcg_ctx);
+    TCGv final_shift = tcg_temp_local_new(tcg_ctx);
+    TCGv res = tcg_temp_local_new(tcg_ctx);
+    TCGv fpsr = tcg_temp_local_new(tcg_ctx);
+
+    end = gen_new_label(tcg_ctx);
+    otherwise = gen_new_label(tcg_ctx);
+    
+
+    /* Load register contents. */
+    gen_get_gpr(tcg_ctx, r1, rs1);
+    gen_get_gpr(tcg_ctx, r2, rs2);
+
+    /* Check if FPSR.CCn is set (with n=fcbit). */
+    gen_get_spr(tcg_ctx, BANK_ID_BASIC_0, FPSR_IDX, fpsr);
+    tcg_gen_movi_i32(tcg_ctx, res, 1);
+    tcg_gen_movi_i32(tcg_ctx, final_shift, 24 + fcbit);
+    tcg_gen_shl_i32(tcg_ctx, res, res, final_shift);
+    tcg_gen_and_i32(tcg_ctx, res, fpsr, res);
+
+    /* If not set, r2 -> r3. */
+    tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, res, 0, otherwise);
+
+    /* If set, do the move ! */
+    gen_set_gpr(tcg_ctx, rs3, r1);
+
+    tcg_gen_br(tcg_ctx, end);
+
+    gen_set_label(tcg_ctx, otherwise);
+
+    gen_set_gpr(tcg_ctx, rs3, r2);
+
+    /* End. */
+    gen_set_label(tcg_ctx, end);
+
+    /* Free variables. */
+    tcg_temp_free(tcg_ctx, r1);
+    tcg_temp_free(tcg_ctx, r2);
+    tcg_temp_free(tcg_ctx, final_shift);
+    tcg_temp_free(tcg_ctx, res);
+    tcg_temp_free(tcg_ctx, fpsr);
+}
+
+void fpu_gen_cmpf_s(CPURH850State *env, DisasContext *ctx, int rs1, int rs2, int fcond, int fcbit)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+    TCGLabel *handle_nan;
+    TCGLabel *end;
+
+    end = gen_new_label(tcg_ctx);
+    handle_nan = gen_new_label(tcg_ctx);
+
+    TCGv r1 = tcg_temp_local_new(tcg_ctx);
+	TCGv r2 = tcg_temp_local_new(tcg_ctx);
+    TCGv nan1 = tcg_temp_local_new(tcg_ctx);
+    TCGv nan2 = tcg_temp_local_new(tcg_ctx);
+    TCGv less = tcg_temp_local_new(tcg_ctx);
+    TCGv equal = tcg_temp_local_new(tcg_ctx);
+    TCGv unordered = tcg_temp_local_new(tcg_ctx);
+    TCGv res = tcg_temp_local_new(tcg_ctx);
+    TCGv final_shift = tcg_temp_local_new(tcg_ctx);
+    TCGv one = tcg_temp_local_new(tcg_ctx);
+    TCGv mask = tcg_temp_local_new(tcg_ctx);
+
+    tcg_gen_movi_i32(tcg_ctx, one, 1);
+
+    /* Load rs1 and rs2 registers. */
+    gen_get_gpr(tcg_ctx, r1, rs1);
+    gen_get_gpr(tcg_ctx, r2, rs2);
+
+    /* If r1 or r2 is a Nan, then error. */
+    gen_helper_f_is_nan_s(tcg_ctx, nan1, tcg_ctx->cpu_env, r1);
+    gen_helper_f_is_nan_s(tcg_ctx, nan2, tcg_ctx->cpu_env, r2);
+    tcg_gen_brcond_i32(tcg_ctx, TCG_COND_EQ, nan1, one, handle_nan);
+    tcg_gen_brcond_i32(tcg_ctx, TCG_COND_EQ, nan2, one, handle_nan);
+
+    gen_helper_flt_s(tcg_ctx, less, tcg_ctx->cpu_env, r2, r1);
+    gen_helper_feq_s(tcg_ctx, equal, tcg_ctx->cpu_env, r2, r1);
+    tcg_gen_movi_i32(tcg_ctx, unordered, 0);
+    tcg_gen_br(tcg_ctx, end);
+
+    gen_set_label(tcg_ctx, handle_nan);
+
+    tcg_gen_movi_i32(tcg_ctx, less, 0);
+    tcg_gen_movi_i32(tcg_ctx, equal, 0);
+    tcg_gen_movi_i32(tcg_ctx, unordered, 1);
+    if (fcond & 0x8)
+    {
+        /* Invalid operation detected. */
+        /* TODO: raise exception ? */
+    }
+
+    /* This is the end =) */
+    gen_set_label(tcg_ctx, end);
+
+    /* Compute logical result. */
+    tcg_gen_movi_i32(tcg_ctx, res, 0);
+    if (fcond & 1)
+        tcg_gen_or_i32(tcg_ctx, res, res, unordered);
+    if (fcond & 2)
+        tcg_gen_or_i32(tcg_ctx, res, res, equal);
+    if (fcond & 4)
+        tcg_gen_or_i32(tcg_ctx, res, res, less);
+    
+    /**
+     * Set CCn bit into FPSR (with n=fcbit).
+     *  1. Load FPSR into r1
+     *  2. AND r1 with NOT bitmask for CCn
+     *  3. OR bitmask if res == 1
+     *  4. Store r1 into FPSR
+     **/
+    gen_get_spr(tcg_ctx, BANK_ID_BASIC_0, FPSR_IDX, r1);
+    tcg_gen_movi_i32(tcg_ctx, final_shift, 24 + fcbit);
+    tcg_gen_shl_i32(tcg_ctx, mask, one, final_shift);
+    tcg_gen_andc_tl(tcg_ctx, r1, r1, mask);
+    tcg_gen_shl_i32(tcg_ctx, res, res, final_shift);
+    tcg_gen_or_i32(tcg_ctx, r1, r1, res);
+    gen_set_spr(tcg_ctx, BANK_ID_BASIC_0, FPSR_IDX, r1);
+
+    /* Free variables. */
+    tcg_temp_free(tcg_ctx, r1);
+    tcg_temp_free(tcg_ctx, r2);
+    tcg_temp_free(tcg_ctx, nan1);
+    tcg_temp_free(tcg_ctx, nan2);
+    tcg_temp_free(tcg_ctx, less);
+    tcg_temp_free(tcg_ctx, equal);
+    tcg_temp_free(tcg_ctx, unordered);
+    tcg_temp_free(tcg_ctx, final_shift);
+    tcg_temp_free(tcg_ctx, one);
+    tcg_temp_free(tcg_ctx, res);
+}
+
+
+/**
+ * Floating-point double-precision IR generators.
+ **/
+
+void fpu_gen_dp_ir_2(CPURH850State *env, DisasContext *ctx, int operands, int op, int rs2, int rs3)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+    /* rs1, rs2 and rs3 for TCG */
+	TCGv_i64 r2 = tcg_temp_local_new_i64(tcg_ctx);
+    TCGv_i64 r3 = tcg_temp_local_new_i64(tcg_ctx);
+    TCGv r3_32 = tcg_temp_local_new_i32(tcg_ctx);
+
+    /* Load contents from registers. */
+    switch(operands)
+    {
+        case FPU_TYPE_D:
+            {
+                /* Extract value from register rs2. */
+                fpu_load_i64(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                switch(op)
+                {
+                    case FPU_OP_ABS:
+                        gen_helper_fabs_d(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_NEG:
+                        gen_helper_fneg_d(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_SQRT:
+                        gen_helper_fsqrt_d(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_RECIP:
+                        gen_helper_frecip_d(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_RSQRT:
+                        gen_helper_frsqrt_d(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+                }
+                
+                /* Store result. */
+                fpu_store_i64(tcg_ctx, rs3, r3);
+            }
+            break;
+
+        case FPU_TYPE_DL:
+            {
+                /* Extract value from register rs2. */
+                fpu_load_i64(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                switch(op)
+                {
+                    case FPU_OP_TRNC:
+                        gen_helper_ftrnc_dl(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CEIL:
+                        gen_helper_fceil_dl(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_FLOOR:
+                        gen_helper_ffloor_dl(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CVT:
+                        gen_helper_fcvt_dl(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                }
+                
+                /* Store result. */
+                fpu_store_i64(tcg_ctx, rs3, r3);
+            }
+            break;
+
+        case FPU_TYPE_DUL:
+            {
+                /* Extract value from register rs2. */
+                fpu_load_i64(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                switch(op)
+                {
+                    case FPU_OP_TRNC:
+                        gen_helper_ftrnc_dul(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CEIL:
+                        gen_helper_fceil_dul(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_FLOOR:
+                        gen_helper_ffloor_dul(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CVT:
+                        gen_helper_fcvt_dul(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                        break;
+
+                }
+                
+                /* Store result. */
+                fpu_store_i64(tcg_ctx, rs3, r3);
+            }
+            break;
+
+
+        case FPU_TYPE_DW:
+            {
+                /* Extract value from register rs2. */
+                fpu_load_i64(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                switch(op)
+                {
+                    case FPU_OP_TRNC:
+                        gen_helper_ftrnc_dw(tcg_ctx, r3_32, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CEIL:
+                        gen_helper_fceil_dw(tcg_ctx, r3_32, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_FLOOR:
+                        gen_helper_ffloor_dw(tcg_ctx, r3_32, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CVT:
+                        gen_helper_fcvt_dw(tcg_ctx, r3_32, tcg_ctx->cpu_env, r2);
+                        break;
+
+                }
+                
+                /* Store result. */
+                gen_set_gpr(tcg_ctx, rs3, r3_32);
+            }
+            break;
+
+        case FPU_TYPE_DUW:
+            {
+                /* Extract value from register rs2. */
+                fpu_load_i64(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                switch(op)
+                {
+                    case FPU_OP_TRNC:
+                        gen_helper_ftrnc_duw(tcg_ctx, r3_32, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CEIL:
+                        gen_helper_fceil_duw(tcg_ctx, r3_32, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_FLOOR:
+                        gen_helper_ffloor_duw(tcg_ctx, r3_32, tcg_ctx->cpu_env, r2);
+                        break;
+
+                    case FPU_OP_CVT:
+                        gen_helper_fcvt_duw(tcg_ctx, r3_32, tcg_ctx->cpu_env, r2);
+                        break;
+
+                }
+                
+                /* Store result. */
+                gen_set_gpr(tcg_ctx, rs3, r3_32);
+            }
+            break;
+
+
+        case FPU_TYPE_LD:
+            {
+                /* Load content from register. */
+                fpu_load_i64(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                if (op == FPU_OP_CVT)
+                {
+                    gen_helper_fcvt_ld(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                }
+                else
+                {
+                    /* Unsupported operation. */
+                }
+
+                /* Store result. */
+                fpu_store_i64(tcg_ctx, rs3, r3);
+            }
+            break;
+
+
+        case FPU_TYPE_WD:
+            {
+                /* Extract value of reg1 and reg2. */
+                gen_get_gpr(tcg_ctx, r3_32, rs2);
+
+                /* Apply operation. */
+                if (op == FPU_OP_CVT)
+                {
+                    gen_helper_fcvt_wd(tcg_ctx, r3, tcg_ctx->cpu_env, r3_32);
+                }
+                else
+                {
+                    /* Unsupported operation. */
+                }
+
+                /* Store result. */
+                fpu_store_i64(tcg_ctx, rs3, r3);
+            }
+            break;
+
+
+        case FPU_TYPE_SD:
+            {
+                /* Extract value of reg1 and reg2. */
+                gen_get_gpr(tcg_ctx, r3_32, rs2);
+
+                /* Apply operation. */
+                if (op == FPU_OP_CVT)
+                {
+                    gen_helper_fcvt_sd(tcg_ctx, r3, tcg_ctx->cpu_env, r3_32);
+                }
+                else
+                {
+                    /* Unsupported operation. */
+                }
+
+                /* Store result. */
+                fpu_store_i64(tcg_ctx, rs3, r3);
+            }
+            break;
+
+        case FPU_TYPE_UWD:
+            {
+                /* Extract value of reg1 and reg2. */
+                gen_get_gpr(tcg_ctx, r3_32, rs2);
+
+                /* Apply operation. */
+                if (op == FPU_OP_CVT)
+                {
+                    gen_helper_fcvt_uwd(tcg_ctx, r3, tcg_ctx->cpu_env, r3_32);
+                }
+                else
+                {
+                    /* Unsupported operation. */
+                }
+
+                /* Store result. */
+                fpu_store_i64(tcg_ctx, rs3, r3);
+            }
+            break;
+
+        case FPU_TYPE_ULD:
+            {
+                /* Load content from register. */
+                fpu_load_i64(tcg_ctx, r2, rs2);
+
+                /* Apply operation. */
+                if (op == FPU_OP_CVT)
+                {
+                    gen_helper_fcvt_uld(tcg_ctx, r3, tcg_ctx->cpu_env, r2);
+                }
+                else
+                {
+                    /* Unsupported operation. */
+                }
+
+                /* Store result. */
+                fpu_store_i64(tcg_ctx, rs3, r3);
+            }
+            break;
+
+    }
+
+    /* Mov softfloat flags into our register. */
+    gen_helper_f_sync_fflags(tcg_ctx, tcg_ctx->cpu_env);
+
+    /* Free temp. */
+    tcg_temp_free_i64(tcg_ctx, r2);
+    tcg_temp_free_i64(tcg_ctx, r3);
+    tcg_temp_free_i32(tcg_ctx, r3_32);
+}
+
+
+void fpu_gen_dp_ir_3(CPURH850State *env, DisasContext *ctx, int operands, int op, int rs1, int rs2, int rs3)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+    /* rs1, rs2 and rs3 for TCG */
+    TCGv_i64 r1 = tcg_temp_local_new_i64(tcg_ctx);
+	TCGv_i64 r2 = tcg_temp_local_new_i64(tcg_ctx);
+    TCGv_i64 r3 = tcg_temp_local_new_i64(tcg_ctx);
+
+    /* Load contents from registers. */
+    switch(operands)
+    {
+        case FPU_TYPE_D:
+            {
+                /* Load float64 values from regpairs designed by rs1 and rs2. */
+                fpu_load_i64_2(tcg_ctx, r1, r2, rs1, rs2);
+            }
+            break;
+    }
+
+    switch(op)
+    {
+        case FPU_OP_ADD:
+            gen_helper_fadd_d(tcg_ctx, r3, tcg_ctx->cpu_env, r1, r2);
+            break;
+
+        case FPU_OP_DIV:
+            gen_helper_fdiv_d(tcg_ctx, r3, tcg_ctx->cpu_env, r2, r1);
+            break;
+
+        case FPU_OP_SUB:
+            gen_helper_fsub_d(tcg_ctx, r3, tcg_ctx->cpu_env, r2, r1);
+            break;
+
+        case FPU_OP_MAX:
+            gen_helper_fmax_d(tcg_ctx, r3, tcg_ctx->cpu_env, r1, r2);
+            break;
+
+        case FPU_OP_MIN:
+            gen_helper_fmin_d(tcg_ctx, r3, tcg_ctx->cpu_env, r1, r2);
+            break;
+
+        case FPU_OP_MUL:
+            gen_helper_fmul_d(tcg_ctx, r3, tcg_ctx->cpu_env, r1, r2);
+            break;
+    }
+
+    switch(operands)
+    {
+        case FPU_TYPE_D:
+            {
+                /* Store result as float64 in regpair designed by rs3. */
+                fpu_store_i64(tcg_ctx, rs3, r3);
+            }
+            break;
+    }
+
+    /* Mov softfloat flags into our register. */
+    gen_helper_f_sync_fflags(tcg_ctx, tcg_ctx->cpu_env);
+
+    /* Free temp. */
+    tcg_temp_free_i64(tcg_ctx, r1);
+    tcg_temp_free_i64(tcg_ctx, r2);
+    tcg_temp_free_i64(tcg_ctx, r3);
+}
+
+
+void fpu_gen_cmpf_d(CPURH850State *env, DisasContext *ctx, int rs1, int rs2, int fcond, int fcbit)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+    TCGLabel *handle_nan;
+    TCGLabel *end;
+
+    end = gen_new_label(tcg_ctx);
+    handle_nan = gen_new_label(tcg_ctx);
+
+    TCGv_i64 r1 = tcg_temp_local_new_i64(tcg_ctx);
+	TCGv_i64 r2 = tcg_temp_local_new_i64(tcg_ctx);
+    TCGv nan1 = tcg_temp_local_new(tcg_ctx);
+    TCGv nan2 = tcg_temp_local_new(tcg_ctx);
+    TCGv less = tcg_temp_local_new(tcg_ctx);
+    TCGv equal = tcg_temp_local_new(tcg_ctx);
+    TCGv unordered = tcg_temp_local_new(tcg_ctx);
+    TCGv res = tcg_temp_local_new(tcg_ctx);
+    TCGv final_shift = tcg_temp_local_new(tcg_ctx);
+    TCGv one = tcg_temp_local_new(tcg_ctx);
+    TCGv mask = tcg_temp_local_new(tcg_ctx);
+
+    tcg_gen_movi_i32(tcg_ctx, one, 1);
+
+    /* Load rs1 and rs2 registers. */
+    fpu_load_i64(tcg_ctx, r1, rs1);
+    fpu_load_i64(tcg_ctx, r2, rs2);
+
+    /* If r1 or r2 is a Nan, then error. */
+    gen_helper_f_is_nan_d(tcg_ctx, nan1, tcg_ctx->cpu_env, r1);
+    gen_helper_f_is_nan_d(tcg_ctx, nan2, tcg_ctx->cpu_env, r2);
+    tcg_gen_or_i32(tcg_ctx, nan1, nan1, nan2);
+    tcg_gen_brcond_i32(tcg_ctx, TCG_COND_EQ, nan1, one, handle_nan);
+    tcg_gen_brcond_i32(tcg_ctx, TCG_COND_EQ, nan2, one, handle_nan);
+
+    gen_helper_flt_d(tcg_ctx, less, tcg_ctx->cpu_env, r2, r1);
+    gen_helper_feq_d(tcg_ctx, equal, tcg_ctx->cpu_env, r2, r1);
+    tcg_gen_movi_i32(tcg_ctx, unordered, 0);
+    tcg_gen_br(tcg_ctx, end);
+
+    gen_set_label(tcg_ctx, handle_nan);
+
+    tcg_gen_movi_i32(tcg_ctx, less, 0);
+    tcg_gen_movi_i32(tcg_ctx, equal, 0);
+    tcg_gen_movi_i32(tcg_ctx, unordered, 1);
+    if (fcond & 0x8)
+    {
+        /* Invalid operation detected. */
+        /* TODO: raise exception ? */
+    }
+
+    /* This is the end =) */
+    gen_set_label(tcg_ctx, end);
+
+    /* Set FPSR.CCn */
+    tcg_gen_movi_i32(tcg_ctx, res, 0);
+    if (fcond & 1)
+        tcg_gen_or_i32(tcg_ctx, res, res, unordered);
+    if (fcond & 2)
+        tcg_gen_or_i32(tcg_ctx, res, res, equal);
+    if (fcond & 4)
+        tcg_gen_or_i32(tcg_ctx, res, res, less);
+    
+    /**
+     * Set CCn bit into FPSR (with n=fcbit).
+     *  1. Load FPSR into r1
+     *  2. AND r1 with NOT bitmask for CCn
+     *  3. OR bitmask if res == 1
+     *  4. Store r1 into FPSR
+     **/
+    gen_get_spr(tcg_ctx, BANK_ID_BASIC_0, FPSR_IDX, nan1);
+    tcg_gen_movi_i32(tcg_ctx, final_shift, 24 + fcbit);
+    tcg_gen_shl_i32(tcg_ctx, mask, one, final_shift);
+    tcg_gen_andc_tl(tcg_ctx, nan1, nan1, mask);
+    tcg_gen_shl_i32(tcg_ctx, res, res, final_shift);
+    tcg_gen_or_i32(tcg_ctx, nan1, nan1, res);
+    gen_set_spr(tcg_ctx, BANK_ID_BASIC_0, FPSR_IDX, nan1);
+
+    /* Free variables. */
+    tcg_temp_free_i64(tcg_ctx, r1);
+    tcg_temp_free_i64(tcg_ctx, r2);
+    tcg_temp_free(tcg_ctx, nan1);
+    tcg_temp_free(tcg_ctx, nan2);
+    tcg_temp_free(tcg_ctx, less);
+    tcg_temp_free(tcg_ctx, equal);
+    tcg_temp_free(tcg_ctx, unordered);
+    tcg_temp_free(tcg_ctx, final_shift);
+    tcg_temp_free(tcg_ctx, one);
+    tcg_temp_free(tcg_ctx, mask);
+}
+
+void fpu_gen_cmov_d(CPURH850State *env, DisasContext *ctx, int rs1, int rs2, int rs3, int fcbit)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+    TCGLabel *end, *otherwise;
+    TCGv_i64 r1 = tcg_temp_local_new_i64(tcg_ctx);
+	TCGv_i64 r2 = tcg_temp_local_new_i64(tcg_ctx);
+    TCGv final_shift = tcg_temp_local_new(tcg_ctx);
+    TCGv res = tcg_temp_local_new(tcg_ctx);
+    TCGv fpsr = tcg_temp_local_new(tcg_ctx);
+
+    end = gen_new_label(tcg_ctx);
+    otherwise = gen_new_label(tcg_ctx);
+    
+
+    /* Load register contents. */
+    fpu_load_i64(tcg_ctx, r1, rs1);
+    fpu_load_i64(tcg_ctx, r2, rs2);
+
+    /* Check if FPSR.CCn is set (with n=fcbit). */
+    gen_get_spr(tcg_ctx, BANK_ID_BASIC_0, FPSR_IDX, fpsr);
+    tcg_gen_movi_i32(tcg_ctx, res, 1);
+    tcg_gen_movi_i32(tcg_ctx, final_shift, 24 + fcbit);
+    tcg_gen_shl_i32(tcg_ctx, res, res, final_shift);
+    tcg_gen_and_i32(tcg_ctx, res, fpsr, res);
+
+    /* If not set, r2 -> r3. */
+    tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, res, 0, otherwise);
+
+    /* If set, do the move ! */
+    fpu_store_i64(tcg_ctx, rs3, r1);
+
+    tcg_gen_br(tcg_ctx, end);
+
+    gen_set_label(tcg_ctx, otherwise);
+
+    fpu_store_i64(tcg_ctx, rs3, r2);
+
+    /* End. */
+    gen_set_label(tcg_ctx, end);
+
+    /* Free variables. */
+    tcg_temp_free_i64(tcg_ctx, r1);
+    tcg_temp_free_i64(tcg_ctx, r2);
+    tcg_temp_free(tcg_ctx, final_shift);
+    tcg_temp_free(tcg_ctx, res);
+    tcg_temp_free(tcg_ctx, fpsr);
+}
+
+
+/**
+ * Instruction decoding and IR generation.
+ **/
+
+void fpu_decode_cat0_instn(CPURH850State *env, DisasContext *ctx)
+{
+    int rs1 = GET_RS1(ctx->opcode);
+    int rs2 = GET_RS2(ctx->opcode);
+    int rs3 = GET_RS3(ctx->opcode);
+    
+    switch(MASK_OP_FORMAT_FI(ctx->opcode))
+    {
+        case OPC_RH850_FPU_GROUP_SW:
+            switch(rs1)
+            {
+                case OPC_RH850_FPU_TRNCF_SW:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SW, FPU_OP_TRNC, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CEILF_SW:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SW, FPU_OP_CEIL, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_FLOORF_SW:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SW, FPU_OP_FLOOR, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_SW:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SW, FPU_OP_CVT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_TRNCF_SUW:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SUW, FPU_OP_TRNC, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CEILF_SUW:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SUW, FPU_OP_CEIL, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_FLOORF_SUW:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SW, FPU_OP_FLOOR, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_SUW:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SUW, FPU_OP_CVT, rs2, rs3);
+                    break;
+            }
+            break;
+
+        case OPC_RH850_FPU_GROUP_DS:
+            switch(rs1)
+            {
+                case OPC_RH850_FPU_CVTF_WS:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_WS, FPU_OP_CVT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_LS:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_LS, FPU_OP_CVT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_HS:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_HS, FPU_OP_CVT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_SH:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SH, FPU_OP_CVT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_UWS:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_UWS, FPU_OP_CVT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_ULS:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_ULS, FPU_OP_CVT, rs2, rs3);
+                    break;
+            }
+            break;
+
+        case OPC_RH850_FPU_GROUP_SL:
+            switch(rs1)
+            {
+                case OPC_RH850_FPU_TRNCF_SL:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SL, FPU_OP_TRNC, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CEILF_SL:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SL, FPU_OP_CEIL, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_FLOORF_SL:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SL, FPU_OP_FLOOR, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_SL:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SL, FPU_OP_CVT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_TRNCF_SUL:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SUL, FPU_OP_TRNC, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CEILF_SUL:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SUL, FPU_OP_CEIL, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_FLOORF_SUL:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SUL, FPU_OP_FLOOR, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_SUL:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_SUL, FPU_OP_CVT, rs2, rs3);
+                    break;
+            }
+            break;
+
+        case OPC_RH850_FPU_GROUP_ABSS:
+            switch(rs1)
+            {
+                case OPC_RH850_FPU_ABSF_S:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_S, FPU_OP_ABS, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_NEGF_S:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_S, FPU_OP_NEG, rs2, rs3);
+                    break;
+            }
+            break;
+
+        case OPC_RH850_FPU_GROUP_S:
+            switch(rs1)
+            {
+                case OPC_RH850_FPU_SQRTF_S:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_S, FPU_OP_SQRT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_RECIPF_S:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_S, FPU_OP_RECIP, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_RSQRTF_S:
+                    fpu_gen_sp_ir_2(env, ctx, FPU_TYPE_S, FPU_OP_RSQRT, rs2, rs3);
+                    break;
+            }
+            break;
+
+        case OPC_RH850_FPU_GROUP_DW:
+            switch(rs1)
+            {
+                case OPC_RH850_FPU_TRNCF_DW:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DW, FPU_OP_TRNC, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CEILF_DW:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DW, FPU_OP_CEIL, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_FLOORF_DW:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DW, FPU_OP_FLOOR, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_DW:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DW, FPU_OP_CVT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_TRNCF_DUW:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DUW, FPU_OP_TRNC, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CEILF_DUW:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DUW, FPU_OP_CEIL, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_FLOORF_DUW:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DUW, FPU_OP_FLOOR, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_DUW:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DUW, FPU_OP_CVT, rs2, rs3);
+                    break;
+            }
+            break;
+
+        case OPC_RH850_FPU_GROUP_DD:
+            switch(rs1)
+            {
+                case OPC_RH850_FPU_CVTF_WD:
+                    //fpu_gen_cvtf_wd(env, ctx, rs2, rs3);
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_WD, FPU_OP_CVT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_LD:
+                    //fpu_gen_cvtf_ld(env, ctx, rs2, rs3);
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_LD, FPU_OP_CVT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_SD:
+                    //fpu_gen_cvtf_sd(env, ctx, rs2, rs3);
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_SD, FPU_OP_CVT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_UWD:
+                    //fpu_gen_cvtf_uwd(env, ctx, rs2, rs3);
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_UWD, FPU_OP_CVT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_ULD:
+                    //fpu_gen_cvtf_uld(env, ctx, rs2, rs3);
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_ULD, FPU_OP_CVT, rs2, rs3);
+                    break;
+            }
+            break;
+
+        case OPC_RH850_FPU_GROUP_DL:
+            switch(rs1)
+            {
+                case OPC_RH850_FPU_TRNCF_DL:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DL, FPU_OP_TRNC, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CEILF_DL:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DL, FPU_OP_CEIL, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_FLOORF_DL:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DL, FPU_OP_FLOOR, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_DL:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DL, FPU_OP_CVT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_TRNCF_DUL:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DUL, FPU_OP_TRNC, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CEILF_DUL:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DUL, FPU_OP_CEIL, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_FLOORF_DUL:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DUL, FPU_OP_FLOOR, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_CVTF_DUL:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_DUL, FPU_OP_CVT, rs2, rs3);
+                    break;
+            }
+            break;
+
+        case OPC_RH850_FPU_GROUP_ABSD:
+            switch(rs1)
+            {
+                case OPC_RH850_FPU_ABSF_D:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_D, FPU_OP_ABS, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_NEGF_D:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_D, FPU_OP_NEG, rs2, rs3);
+                    break;
+            }
+            break;
+
+        case OPC_RH850_FPU_GROUP_D:
+            switch(rs1)
+            {
+                case OPC_RH850_FPU_SQRTF_D:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_D, FPU_OP_SQRT, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_RECIPF_D:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_D, FPU_OP_RECIP, rs2, rs3);
+                    break;
+
+                case OPC_RH850_FPU_RSQRTF_D:
+                    fpu_gen_dp_ir_2(env, ctx, FPU_TYPE_D, FPU_OP_RSQRT, rs2, rs3);
+                    break;
+            }
+            break;
+
+        case OPC_RH850_FPU_ADDF_S:
+            fpu_gen_sp_ir_3(env, ctx, FPU_TYPE_S, FPU_OP_ADD, rs1, rs2, rs3);
+            break;
+
+        case OPC_RH850_FPU_ADDF_D:
+            /* rs1, rs2 and rs3 must have bit 0 set to 0. */
+            if ((rs1 & 1) || (rs2 & 1) || (rs3 & 1))
+            {
+                /* TODO: Invalid instruction, must trigger exception.  */
+            }
+            else
+                fpu_gen_dp_ir_3(env, ctx, FPU_TYPE_D, FPU_OP_ADD, rs1, rs2, rs3);
+            break;
+
+        case OPC_RH850_FPU_SUBF_S:
+            fpu_gen_sp_ir_3(env, ctx, FPU_TYPE_S, FPU_OP_SUB, rs1, rs2, rs3);
+            break;
+
+        case OPC_RH850_FPU_SUBF_D:
+            fpu_gen_dp_ir_3(env, ctx, FPU_TYPE_D, FPU_OP_SUB, rs1, rs2, rs3);
+            break;
+
+        case OPC_RH850_FPU_MULF_S:
+            fpu_gen_sp_ir_3(env, ctx, FPU_TYPE_S, FPU_OP_MUL, rs1, rs2, rs3);
+            break;
+
+        case OPC_RH850_FPU_MULF_D:
+            fpu_gen_dp_ir_3(env, ctx, FPU_TYPE_D, FPU_OP_MUL, rs1, rs2, rs3);
+            break;
+
+        case OPC_RH850_FPU_MAXF_S:
+            fpu_gen_sp_ir_3(env, ctx, FPU_TYPE_S, FPU_OP_MAX, rs1, rs2, rs3);
+            break;
+
+        case OPC_RH850_FPU_MAXF_D:
+            fpu_gen_dp_ir_3(env, ctx, FPU_TYPE_D, FPU_OP_MAX, rs1, rs2, rs3);
+            break;
+
+        case OPC_RH850_FPU_MINF_S:
+            fpu_gen_sp_ir_3(env, ctx, FPU_TYPE_S, FPU_OP_MIN, rs1, rs2, rs3);
+            break;
+
+        case OPC_RH850_FPU_MINF_D:
+            fpu_gen_dp_ir_3(env, ctx, FPU_TYPE_D, FPU_OP_MIN, rs1, rs2, rs3);
+            break;
+
+        case OPC_RH850_FPU_DIVF_S:
+            fpu_gen_sp_ir_3(env, ctx, FPU_TYPE_S, FPU_OP_DIV, rs1, rs2, rs3);
+            break;
+
+        case OPC_RH850_FPU_DIVF_D:
+            fpu_gen_dp_ir_3(env, ctx, FPU_TYPE_D, FPU_OP_DIV, rs1, rs2, rs3);
+            break;
+
+
+        default:
+            switch(ctx->opcode & (0x70 << 16))
+            {
+                case OPC_RH850_FPU_CMOV_S_OR_TRFSR:
+
+                    /* If reg1==reg2==reg3==0, then it is a TRSFR instruction. */
+                    if ((rs1 == 0) && (rs2 == 0) && (rs3 == 0))
+                    {
+                        fpu_gen_trfsr(env, ctx, (ctx->opcode & (0xe << 16))>>17 );
+                    }
+                    else
+                    {
+                        /* Call generator with fcbit. */
+                        fpu_gen_cmov_s(env, ctx, rs1, rs2, rs3, (ctx->opcode & (0xe << 16))>>17 );
+                    }
+                    break;
+
+                case OPC_RH850_FPU_CMOV_D:
+                    /* Call generator with fcbit. */
+                    fpu_gen_cmov_d(env, ctx, rs1, rs2, rs3, (ctx->opcode & (0xe << 16))>>17 );
+                    break;
+
+                case OPC_RH850_FPU_CMP_S:
+                    /* Call generator with fcond (rs3) and fcbit. */
+                    fpu_gen_cmpf_s(env, ctx, rs1, rs2, rs3, (ctx->opcode & (0xe << 16))>>17 );
+                    break;
+
+                case OPC_RH850_FPU_CMP_D:
+                    /* Call generator with fcond (rs3) and fcbit. */
+                    fpu_gen_cmpf_d(env, ctx, rs1, rs2, rs3, (ctx->opcode & (0xe << 16))>>17 );
+                    break;
+
+                default:
+                    /* Unknown inst. */
+                    break;
+            }
+            break;
+    }
+}
+
+void fpu_decode_cat1_instn(CPURH850State *env, DisasContext *ctx)
+{
+    int rs1 = GET_RS1(ctx->opcode);
+    int rs2 = GET_RS2(ctx->opcode);
+    int rs3 = GET_RS3(ctx->opcode);
+
+    fpu_gen_cat1_ir(env, ctx, MASK_OP_FORMAT_FI(ctx->opcode), rs1, rs2, rs3);
+}
+
+/**
+ * Initialize FPU.
+ **/
+
+void rh850_fpu_translate_init(void)
+{
+}
\ No newline at end of file
diff --git a/qemu/target/rh850/fpu_translate.h b/qemu/target/rh850/fpu_translate.h
new file mode 100644
index 0000000000..b21af6759f
--- /dev/null
+++ b/qemu/target/rh850/fpu_translate.h
@@ -0,0 +1,41 @@
+/*
+ * QEMU RH850 CPU
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2017-2018 SiFive, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RH850_FPU_H
+#define RH850_FPU_H
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "tcg/tcg-op.h"
+#include "translate.h"
+#include "fpu_translate.h"
+#include "exec/cpu_ldst.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
+#include "exec/translator.h"
+#include "translate.h"
+
+void fpu_decode_cat0_instn(CPURH850State *env, DisasContext *ctx);
+void fpu_decode_cat1_instn(CPURH850State *env, DisasContext *ctx);
+void fpu_init(CPURH850State *env);
+void rh850_fpu_translate_init(void);
+
+#endif /* RH850_FPU_H */
\ No newline at end of file
diff --git a/qemu/target/rh850/gdbstub.c b/qemu/target/rh850/gdbstub.c
new file mode 100644
index 0000000000..2abc97fb64
--- /dev/null
+++ b/qemu/target/rh850/gdbstub.c
@@ -0,0 +1,169 @@
+/*
+ * RH850 GDB Server Stub
+ *
+ * Copyright (c) 2019-2020 Marko Klopcic, iSYSTEM Labs
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+#include "cpu.h"
+
+/* Mapping of winIDEA register index to env->sysBasicRegs() index. (see mail
+ * from Matic 2019-05-06 and isystem/doc/v850-tdep.c)
+       QEMU idx             wI idx
+        32, //      eipc      0
+        33, //      eipsw     1
+        34, //      fepc      2
+        35, //      fepsw     3
+        37, //      psw       4
+       128, //      fpsr      5
+       129, //      fpepc     6
+       130, //      fpst      7
+       131, //      fpcc      8
+       132, //      fpcfg     9
+       133, //      fpec     10
+        44, //      SESR    N/A
+        45, //      EIIC     11
+        46, //  	FEIC     12
+        48, //      CTPC     13
+        49, //      CTPSW    14
+        52, //      CTBP     15
+        60, //      EIWR     16
+        61, //      FEWR     17
+        63, //      BSEL     18
+       150, //      mcfg0    19
+       152, //	    RBASE    20
+       153, //      EBASE    21
+       154, //      intbp    22
+       155, //      mctl	 23
+       156, //      pid      24
+       161, //      sccfg    25
+       162, //      scbp     26
+       182, //      htcfg0   27
+       188, //      mea      28
+       189, //      asid     29
+       190  //      mei      30
+*/
+#define BANK_MASK  0xf0000
+#define BANK_SHIFT 16
+#define SRI(selID, regID) (((selID) << BANK_SHIFT) | (regID))
+#define SRI0(regID) (regID)
+#define SRI1(regID) SRI(1, (regID))
+#define SRI2(regID) SRI(2, (regID))
+
+typedef int IdxType;
+const IdxType winIdeaRegIdx2qemuSysRegIdx[] = {
+// 0          1            2            3            4            5            6            7            8            9
+// ---------------------------------------------
+-1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,        //  0
+-1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,        //  1
+-1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,        //  2
+
+-1,          -1, SRI0(EIPC_IDX), SRI0(EIPSW_IDX),SRI0(FEPC_IDX),SRI0(FEPSW_IDX),-1, SRI0(PSW_IDX),      -1,          -1,        //  3
+-1,          -1,          -1,          -1,          -1, SRI0(EIIC_IDX),SRI0(FEIC_IDX),-1,SRI0(CTPC_IDX),SRI0(CTPSW_IDX),        //  4
+-1,          -1,   SRI0(CTBP_IDX),     -1,          -1,          -1,          -1,          -1,          -1,          -1,        //  5
+
+SRI0(EIWR_IDX),SRI0(FEWR_IDX),-1,SRI0(BSEL_IDX),    -1,          -1,          -1,          -1,          -1,          -1,        //  6
+-1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,        //  7
+-1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,        //  8
+
+-1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,        //  9
+-1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,        // 10
+-1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,        // 11
+
+-1,          -1,          -1,          -1,          -1,          -1,          -1,          -1, SRI0(FPSR_IDX), SRI0(FEPC_IDX),        // 12
+SRI0(FPST_IDX),SRI0(FPCC_IDX),SRI0(FPCFG_IDX),SRI0(FPEC_IDX), -1,-1,          -1,          -1,          -1,          -1,        // 13
+-1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,        // 14
+
+SRI1(MCFG0_IDX1),-1,SRI1(RBASE_IDX1),SRI1(EBASE_IDX1),SRI1(INTBP_IDX1),SRI1(MCTL_IDX1),SRI1(PID_IDX1),-1,-1,          -1,       // 15
+-1, SRI1(SCCFG_IDX1), SRI1(SCBP_IDX1),  -1,          -1,          -1,          -1,          -1,          -1,          -1,       // 16
+-1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,        // 17
+
+-1,          -1,SRI2(HTCFG0_IDX2),     -1,          -1,          -1,          -1,          -1,SRI2(MEA_IDX2),SRI2(ASID_IDX2),   // 18
+SRI2(MEI_IDX2), -1,       -1,          -1,          -1,          -1,          -1,          -1,          -1,          -1,        // 19
+};
+
+const int NUM_GDB_REGS = sizeof(winIdeaRegIdx2qemuSysRegIdx) / sizeof(IdxType);
+
+int rh850_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    RH850CPU *cpu = RH850_CPU(cs);
+    CPURH850State *env = &cpu->env;
+
+    if (n < 32) {
+        return gdb_get_regl(mem_buf, env->gpRegs[n]);  //gpr is now supposed to be progRegs
+    } else if (n == 64) {
+        return gdb_get_regl(mem_buf, env->pc);
+    } else if (n < NUM_GDB_REGS) {
+    	int sysRegIdx = winIdeaRegIdx2qemuSysRegIdx[n];
+    	if (sysRegIdx >= 0) {
+            int selID = sysRegIdx >> BANK_SHIFT;
+            int regID = sysRegIdx & ~BANK_MASK;
+            if (selID ==  BANK_ID_BASIC_0  &&  regID == PSW_IDX) {
+                int psw = env->Z_flag | (env->S_flag  << 1) | (env->OV_flag << 2) | (env->CY_flag << 3);
+                psw |= (env->SAT_flag << 4) | (env->ID_flag << 5) | (env->EP_flag << 6);
+                psw |= (env->NP_flag << 7) | (env->EBV_flag << 15) | (env->CU0_flag << 16);
+                psw |= (env->CU1_flag << 17) | (env->CU2_flag << 18) | (env->UM_flag << 30);
+                return gdb_get_regl(mem_buf, psw);
+            } else {
+                return gdb_get_regl(mem_buf, env->systemRegs[selID][regID]); // eipc, eipsw, fepc, fepsw, psw, ...
+            }
+    	}
+    }
+
+    *((uint32_t *)mem_buf) = 0xBAD0BAD0;
+    return 4; // registers in slots not set above are ignored
+}
+
+int rh850_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    RH850CPU *cpu = RH850_CPU(cs);
+    CPURH850State *env = &cpu->env;
+    // at the moment our GDB server has different indices for writing single register
+    // will fix this if batch write will have to be supported or interfacing
+    // to other GDB servers for RH850 will be needed.
+    if (n > 0  &&  n < 32) {  // skip R0, because it is always 0
+        env->gpRegs[n] = ldtul_p(mem_buf);
+    } else if (n == 64) {
+        env->pc = ldtul_p(mem_buf);
+    } else if (n < NUM_GDB_REGS) {
+    	int sysRegIdx = winIdeaRegIdx2qemuSysRegIdx[n];
+    	if (sysRegIdx >= 0) {
+    	    int selID = sysRegIdx >> BANK_SHIFT;
+    	    int regID = sysRegIdx & ~BANK_MASK;
+            if (selID ==  BANK_ID_BASIC_0  &&  regID == PSW_IDX) {
+                int psw = ldtul_p(mem_buf);
+                env->Z_flag = psw & 1;
+                env->S_flag = (psw >> 1) & 1;
+                env->OV_flag = (psw >> 2) & 1;
+                env->CY_flag = (psw >> 3) & 1;
+                env->SAT_flag = (psw >> 4) & 1;
+                env->ID_flag = (psw >> 5) & 1;
+                env->EP_flag = (psw >> 6) & 1;
+                env->NP_flag = (psw >> 7) & 1;
+                env->EBV_flag = (psw >> 15) & 1;
+                env->CU0_flag = (psw >> 16) & 1;
+                env->CU1_flag = (psw >> 17) & 1;
+                env->CU2_flag = (psw >> 18) & 1;
+                env->UM_flag = (psw >> 30) & 1;
+            } else {
+                env->systemRegs[selID][regID] = ldtul_p(mem_buf); // eipc, eipsw, fepc, fepsw, psw, ...
+            }
+    	}
+    }
+
+    return sizeof(target_ulong);
+}
diff --git a/qemu/target/rh850/helper.c b/qemu/target/rh850/helper.c
new file mode 100644
index 0000000000..ee171f0dbb
--- /dev/null
+++ b/qemu/target/rh850/helper.c
@@ -0,0 +1,539 @@
+/*
+ * RH850 emulation helpers for qemu.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2017-2018 SiFive, Inc.
+ * Copyright (c) 2018-2019 iSYSTEM Labs d.o.o.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+
+#define RH850_DEBUG_INTERRUPT 0
+
+int rh850_cpu_mmu_index(CPURH850State *env, bool ifetch)
+{
+  return 0;
+}
+
+#ifndef CONFIG_USER_ONLY
+/*
+ * Return RH850 IRQ number if an interrupt should be taken, else -1.
+ * Used in cpu-exec.c
+ *
+ * Adapted from Spike's processor_t::take_interrupt()
+ */
+
+#if 0 /* Not used */
+static int rh850_cpu_hw_interrupts_pending(CPURH850State *env)
+{
+
+    return EXCP_NONE;
+}
+#endif
+#endif
+
+uint32_t psw2int(CPURH850State * env);
+uint32_t mem_deref_4(CPUState * cs, uint32_t addr);
+
+
+uint32_t psw2int(CPURH850State * env)
+{
+  uint32_t ret = 0; 
+  ret |= env->UM_flag<<30;
+  ret |= env->CU0_flag<<16;
+  ret |= env->CU1_flag<<17;
+  ret |= env->CU2_flag<<18;
+  ret |= env->EBV_flag<<15;
+  ret |= env->NP_flag<<7;
+  ret |= env->EP_flag<<6;
+  ret |= env->ID_flag<<5; 
+  ret |= env->SAT_flag<<4;
+  ret |= env->CY_flag<<3;
+  ret |= env->OV_flag<<2;
+  ret |= env->S_flag<<1;
+  ret |= env->Z_flag; 
+
+  return ret;
+}
+
+/*
+ * RH850 interrupt handler.
+ **/
+
+bool rh850_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+#if !defined(CONFIG_USER_ONLY)
+    RH850CPU *cpu = RH850_CPU(cs);
+    CPURH850State *env = &cpu->env;
+
+    //qemu_log("[cpu] exec_interrupt: got interrupt_req=%08x\n", interrupt_request);
+
+    /* Handle FENMI interrupt. */
+    if (interrupt_request == RH850_INT_FENMI)
+    {
+        /* Set exception info. */
+        cs->exception_index = RH850_EXCP_FENMI;
+        env->exception_cause = 0xE0;
+        env->exception_priority = 1;
+
+        /* Acknowledge interrupt. */
+        rh850_cpu_do_interrupt(cs);
+    }
+    else if (interrupt_request == RH850_INT_FEINT)
+    {
+        if (!(env->systemRegs[BANK_ID_BASIC_2][PMR_IDX2] & (1<<env->exception_priority)))
+        {
+            /* Set exception info. */
+            cs->exception_index = RH850_EXCP_FEINT;
+            env->exception_cause = 0xF0;
+            env->exception_priority = 3;
+
+            /* Acknowledge interrupt. */
+            rh850_cpu_do_interrupt(cs);
+        }
+    }
+    else if (interrupt_request == RH850_EXCP_EIINT)
+    {
+        //qemu_log("exec_interrupt got RH850_EXCP_EIINT\n");
+
+        /* Get interrupt request number. */
+        //int intn = env->exception_cause & 0xfff;
+        int priority = 4;
+
+        //qemu_log("[cpu] exec_interrupt: got interrupt_req=%08x\n", interrupt_request);
+
+        /* Check if interrupt priority is not masked (through PMR). */
+        if (!(env->systemRegs[BANK_ID_BASIC_2][PMR_IDX2] & (1<<priority)))
+        {
+            /**
+             * Interrupt is not masked, process it.
+             * We set the exception index to RH850_EXCP_EIINT to notify an EIINT interrupt,
+             * and we set the exception cause to indicate the channel.
+             **/
+
+            /* Set exception info. */
+            cs->exception_index = RH850_EXCP_EIINT;
+            //env->exception_cause = 0x1000 | (intn);
+            //env->exception_dv = !(interrupt_request & RH850_INT_TAB_REF);
+            env->exception_priority = priority;
+
+            /* Acknowledge interrupt. */
+            rh850_cpu_do_interrupt(cs);
+        }
+        else
+        {
+            //qemu_log("[cpu] interrupt priority is masked\n");
+        }
+    }
+#endif
+
+    /* Interrupt request has been processed. */
+    cs->interrupt_request = 0;
+    return false;
+}
+
+#if !defined(CONFIG_USER_ONLY)
+
+
+static int get_physical_address(CPURH850State *env, hwaddr *physical,
+                                int *prot, target_ulong addr,
+                                int access_type, int mmu_idx)
+{
+    
+        /*
+         * There is no memory virtualization in RH850 (at least for the targeted SoC)
+         * Address resolution is straightforward 
+         */
+        *physical = addr;
+        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+        return TRANSLATE_SUCCESS;
+
+}
+
+static void raise_mmu_exception(CPURH850State *env, target_ulong address,
+                                MMUAccessType access_type)
+{
+    CPUState *cs = CPU(rh850_env_get_cpu(env));
+    int page_fault_exceptions = RH850_EXCP_INST_PAGE_FAULT; 
+    switch (access_type) {
+    case MMU_INST_FETCH:
+        cs->exception_index = page_fault_exceptions ?
+            RH850_EXCP_INST_PAGE_FAULT : RH850_EXCP_INST_ACCESS_FAULT;
+        break;
+    case MMU_DATA_LOAD:
+        cs->exception_index = page_fault_exceptions ?
+            RH850_EXCP_LOAD_PAGE_FAULT : RH850_EXCP_LOAD_ACCESS_FAULT;
+        break;
+    case MMU_DATA_STORE:
+        cs->exception_index = page_fault_exceptions ?
+            RH850_EXCP_STORE_PAGE_FAULT : RH850_EXCP_STORE_AMO_ACCESS_FAULT;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    env->badaddr = address;
+}
+
+hwaddr rh850_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
+{
+    RH850CPU *cpu = RH850_CPU(cs);
+    hwaddr phys_addr;
+    int prot;
+    int mmu_idx = cpu_mmu_index(&cpu->env, false);
+
+    if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0, mmu_idx)) {
+        return -1;
+    }
+    return phys_addr;
+}
+
+void rh850_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
+                                   MMUAccessType access_type, int mmu_idx,
+                                   uintptr_t retaddr)
+{
+    RH850CPU *cpu = RH850_CPU(cs);
+    CPURH850State *env = &cpu->env;
+    switch (access_type) {
+    case MMU_INST_FETCH:
+        cs->exception_index = RH850_EXCP_INST_ADDR_MIS;
+        break;
+    case MMU_DATA_LOAD:
+        cs->exception_index = RH850_EXCP_LOAD_ADDR_MIS;
+        break;
+    case MMU_DATA_STORE:
+        cs->exception_index = RH850_EXCP_STORE_AMO_ADDR_MIS;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    env->badaddr = addr;
+    //qemu_log_mask(CPU_LOG_INT, "%s\n", __func__);
+    do_raise_exception_err(env, cs->exception_index, retaddr);
+}
+
+#endif
+
+int rh850_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
+        int rw, int mmu_idx)
+{
+
+
+    /*
+     * TODO: Add check to system register concerning MPU configuratuon MPLA, MPUA
+     *
+     */
+    RH850CPU *cpu = RH850_CPU(cs);
+    CPURH850State *env = &cpu->env;
+#if !defined(CONFIG_USER_ONLY)
+    hwaddr pa = 0;
+    int prot;
+#endif
+    int ret = TRANSLATE_FAIL;
+    qemu_log_mask(CPU_LOG_MMU,
+            "%s pc " TARGET_FMT_lx " ad %" VADDR_PRIx " rw %d mmu_idx \
+             %d\n", __func__, env->pc, address, rw, mmu_idx);
+
+#if !defined(CONFIG_USER_ONLY)
+
+    ret = get_physical_address(env, &pa, &prot, address, rw, mmu_idx);
+    qemu_log_mask(CPU_LOG_MMU,
+            "%s address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx
+             " prot %d\n", __func__, address, ret, pa, prot);
+    if (ret == TRANSLATE_SUCCESS) {
+        tlb_set_page(cs, address & TARGET_PAGE_MASK, pa & TARGET_PAGE_MASK,
+                     prot, mmu_idx, TARGET_PAGE_SIZE);
+    } else if (ret == TRANSLATE_FAIL) {
+        raise_mmu_exception(env, address, rw);
+    }
+#else
+    switch (rw) {
+    case MMU_INST_FETCH:
+        cs->exception_index = RH850_EXCP_INST_PAGE_FAULT;
+        break;
+    case MMU_DATA_LOAD:
+        cs->exception_index = RH850_EXCP_LOAD_PAGE_FAULT;
+        break;
+    case MMU_DATA_STORE:
+        cs->exception_index = RH850_EXCP_STORE_PAGE_FAULT;
+        break;
+    }
+#endif
+    return ret;
+}
+
+
+uint32_t mem_deref_4(CPUState * cs, uint32_t addr){
+          uint8_t * buf = g_malloc(4); 
+          uint32_t ret_dword = 0;
+          cpu_memory_rw_debug(cs, addr,  buf, 4, false); 
+          
+          ret_dword |= buf[3] << 24;
+          ret_dword |= buf[2] << 16;
+          ret_dword |= buf[1] << 8; 
+          ret_dword |= buf[0]; 
+          g_free(buf); 
+          return ret_dword; 
+}
+
+
+void rh850_cpu_do_interrupt(CPUState *cs)
+{
+
+    //qemu_log("[cpu] rh850_cpu_do_interrupt()\n");
+    //qemu_log_mask(CPU_LOG_INT, "%s\n", __func__);
+#if !defined(CONFIG_USER_ONLY)
+    uint32_t intbp;
+    RH850CPU *cpu = RH850_CPU(cs);
+    CPURH850State *env = &cpu->env;
+
+    uint32_t direct_vector_ba; 
+    qemu_log_mask(CPU_LOG_INT, "%s: entering switch\n", __func__);
+    switch (cs->exception_index) {
+        case RH850_EXCP_FETRAP: 
+
+            qemu_log_mask(CPU_LOG_INT, "%s: entering FETRAP handler\n", __func__);
+            // store PSW to FEPSW (and update env->EBV_flag)
+            env->systemRegs[BANK_ID_BASIC_0][FEPSW_IDX] = psw2int(env);
+            // store PC to FEPC
+            env->systemRegs[BANK_ID_BASIC_0][FEPC_IDX] = env->pc+2;
+            // Set Exception Cause
+		    env->systemRegs[BANK_ID_BASIC_0][FEIC_IDX] = env->exception_cause;
+
+            qemu_log_mask(CPU_LOG_INT, "%s, saved pc : %x\n", __func__,env->pc);
+
+            // update PSW
+            env->UM_flag = 0;
+            env->NP_flag = 1;
+            env->EP_flag = 1;
+            env->ID_flag = 1;
+
+            // modify PC, keep RBASE or EBASE bits 9 to 31 (discard bits 0 to 8)
+            if (env->EBV_flag) 
+                direct_vector_ba = env->systemRegs[BANK_ID_BASIC_1][EBASE_IDX1] & 0xFFFFFE00;
+            else
+                direct_vector_ba = env->systemRegs[BANK_ID_BASIC_1][RBASE_IDX1] & 0xFFFFFE00; 
+    
+            qemu_log_mask(CPU_LOG_INT, "%s: direct vector addr : %x \n", __func__,direct_vector_ba);
+            env->pc = direct_vector_ba + 0x30; 
+            break; 
+        
+        case RH850_EXCP_TRAP:
+            qemu_log_mask(CPU_LOG_INT, "%s: entering TRAP handler\n", __func__);
+            // store PSW to EIPSW
+            env->systemRegs[BANK_ID_BASIC_0][EIPSW_IDX] = psw2int(env);
+            // store PC to EIPC
+            env->systemRegs[BANK_ID_BASIC_0][EIPC_IDX] = env->pc+4;
+            // Set Exception Cause
+            env->systemRegs[BANK_ID_BASIC_0][EIIC_IDX] = env->exception_cause;
+
+            env->UM_flag = 0;
+            env->EP_flag = 1;
+            env->ID_flag = 1;
+
+            // modify PC, keep RBASE or EBASE bits 9 to 31 (discard bits 0 to 8)
+            if (env->EBV_flag)
+                direct_vector_ba = env->systemRegs[BANK_ID_BASIC_1][EBASE_IDX1] & 0xFFFFFE00;
+            else
+                direct_vector_ba = env->systemRegs[BANK_ID_BASIC_1][RBASE_IDX1] & 0xFFFFFE00; 
+
+            if (env->exception_cause < 0x50) {
+            env->pc = direct_vector_ba + 0x40; 
+            } else {
+            env->pc = direct_vector_ba + 0x50; 
+            }
+            break; 
+
+        case RH850_EXCP_RIE:
+            //qemu_log("%s: entering RIE handler\n", __func__);
+            // store PSW to FEPSW
+            env->systemRegs[BANK_ID_BASIC_0][FEPSW_IDX] = psw2int(env);
+            // store PC to FEPC
+            env->systemRegs[BANK_ID_BASIC_0][FEPC_IDX] = env->pc;
+            // Set Exception Cause
+                env->systemRegs[BANK_ID_BASIC_0][FEIC_IDX] = env->exception_cause;
+            //qemu_log("%s, saved pc : %x\n", __func__,env->pc);
+            // update PSW
+
+            env->UM_flag = 0;
+            env->NP_flag = 1;
+            env->EP_flag = 1;
+            env->ID_flag = 1;
+
+            // modify PC, keep RBASE or EBASE bits 9 to 31 (discard bits 0 to 8)
+            if (env->EBV_flag) 
+                direct_vector_ba = env->systemRegs[BANK_ID_BASIC_1][EBASE_IDX1] & 0xFFFFFE00;
+            else
+                direct_vector_ba = env->systemRegs[BANK_ID_BASIC_1][RBASE_IDX1] & 0xFFFFFE00; 
+
+            //qemu_log("%s: direct vector addr : %x \n", __func__,direct_vector_ba);
+            env->pc = direct_vector_ba + 0x60;
+            //qemu_log("%s: pc : 0x%08x \n", __func__, direct_vector_ba+0x60); 
+            break;
+
+        case RH850_EXCP_SYSCALL:
+          qemu_log_mask(CPU_LOG_INT, "%s: entering SYSCALL handler\n", __func__);
+          uint32_t syscall_cfg = env->systemRegs[BANK_ID_BASIC_1][SCCFG_IDX1] & 0xff;
+          uint32_t syscall_number = env->exception_cause - 0x8000; 
+          uint32_t syscall_bp = env->systemRegs[BANK_ID_BASIC_1][SCBP_IDX1]; 
+          uint32_t handler_offset=0, deref_addr=0;
+          
+          if (syscall_number <= syscall_cfg) {
+            deref_addr = syscall_bp + (syscall_number<<2); 
+          } else {
+
+            deref_addr = syscall_bp; 
+          }
+
+          qemu_log_mask(CPU_LOG_INT, "%s syscall_cfg_size = %d\n", __func__,syscall_cfg);
+          qemu_log_mask(CPU_LOG_INT, "%s syscall_bp = %d\n", __func__,syscall_bp);
+          qemu_log_mask(CPU_LOG_INT, "%s syscall_num = %d\n", __func__,syscall_number);
+          qemu_log_mask(CPU_LOG_INT, "%s deref_addr = 0x%x\n", __func__,deref_addr);
+          handler_offset = mem_deref_4(cs,deref_addr); 
+          qemu_log_mask(CPU_LOG_INT, "%s handler offset = %x\n", __func__,handler_offset);
+
+          // store PSW to EIPSW
+          env->systemRegs[BANK_ID_BASIC_0][EIPSW_IDX] = psw2int(env);
+          // store PC to EIPC
+          env->systemRegs[BANK_ID_BASIC_0][EIPC_IDX] = env->pc+4;
+          // Set Exception Cause
+		  env->systemRegs[BANK_ID_BASIC_0][EIIC_IDX] = env->exception_cause;
+
+          env->UM_flag = 0;
+          env->EP_flag = 1;
+          env->ID_flag = 1;
+
+          // modify PC 
+          env->pc = syscall_bp + handler_offset; 
+          qemu_log_mask(CPU_LOG_INT, "%s: moving pc to = 0x%x\n", __func__,env->pc);
+          
+          break; 
+
+        case RH850_EXCP_FEINT:
+            //qemu_log("[cpu] entering FEINT handler\n");
+            // store PSW to FEPSW
+            env->systemRegs[BANK_ID_BASIC_0][FEPSW_IDX] = psw2int(env);
+            // store PC to FEPC
+            env->systemRegs[BANK_ID_BASIC_0][FEPC_IDX] = env->pc;
+            // Set Exception Cause
+            env->systemRegs[BANK_ID_BASIC_0][FEIC_IDX] = env->exception_cause;
+
+            /* Update PSW. */
+            env->UM_flag = 0;
+            env->ID_flag = 1;
+            env->NP_flag = 1;
+            env->EP_flag = 0;
+
+            /* Direct vector. */
+            if (env->EBV_flag) 
+                direct_vector_ba = env->systemRegs[BANK_ID_BASIC_1][EBASE_IDX1];
+            else
+                direct_vector_ba = env->systemRegs[BANK_ID_BASIC_1][RBASE_IDX1]; 
+           
+            /* Redirect to FEINT exception handler. */
+            env->pc = (direct_vector_ba & 0xFFFFFF00) + 0xF0;  
+            //qemu_log("%s: moving pc to = 0x%x\n", __func__,env->pc);
+            break;
+
+        case RH850_EXCP_FENMI:
+            //qemu_log("[cpu] entering FENMI handler\n");
+            // store PSW to FEPSW
+            env->systemRegs[BANK_ID_BASIC_0][FEPSW_IDX] = psw2int(env);
+            // store PC to FEPC
+            env->systemRegs[BANK_ID_BASIC_0][FEPC_IDX] = env->pc;
+            // Set Exception Cause
+            env->systemRegs[BANK_ID_BASIC_0][FEIC_IDX] = env->exception_cause;
+
+            /* Update PSW. */
+            env->UM_flag = 0;
+            env->ID_flag = 1;
+            env->NP_flag = 1;
+            env->EP_flag = 0;
+
+            /* Direct vector. */
+            if (env->EBV_flag) 
+                direct_vector_ba = env->systemRegs[BANK_ID_BASIC_1][EBASE_IDX1];
+            else
+                direct_vector_ba = env->systemRegs[BANK_ID_BASIC_1][RBASE_IDX1]; 
+           
+            /* Redirect to FENMI exception handler. */
+            env->pc = (direct_vector_ba & 0xFFFFFF00) + 0xE0;  
+            break;
+
+        case RH850_EXCP_EIINT:
+            //qemu_log("[cpu] entering EIINT handler\n");
+            //qemu_log_mask(CPU_LOG_INT, "%s: entering EIINT handler\n", __func__);
+
+            // store PSW to EIPSW
+            env->systemRegs[BANK_ID_BASIC_0][EIPSW_IDX] = psw2int(env);
+            // store PC to EIPC
+            env->systemRegs[BANK_ID_BASIC_0][EIPC_IDX] = env->pc;
+            // Set Exception Cause
+            env->systemRegs[BANK_ID_BASIC_0][EIIC_IDX] = env->exception_cause;
+            // Set priority to ISPR
+            env->systemRegs[BANK_ID_BASIC_2][ISPR_IDX2] |= (1 << env->exception_priority);
+
+            /* Set PSW.ID (disable further EI exceptions). */
+            env->ID_flag = 1;
+
+            /* Clear PSW.EP (we are processing an interrupt). */
+            env->EP_flag = 0;
+
+            /* Modify PC based on dispatch method (direct vector or table reference). */
+            if (!env->exception_dv)
+            {
+                //qemu_log("[cpu] dispatch EIINT (table reference) for IRQ %d\n", env->exception_cause&0x1ff);
+                /* Table reference, first read INTBP value. */
+                intbp = env->systemRegs[BANK_ID_BASIC_1][INTBP_IDX1];
+                //qemu_log("[cpu] INTBP=0x%08x\n", intbp);
+
+                /* Compute address of interrupt handler (based on channel). */
+                env->pc = mem_deref_4(cs, intbp + 4*(env->exception_cause & 0x1ff));
+                //qemu_log("[cpu] PC=0x%08x\n", env->pc);
+            }
+            else
+            {
+                //qemu_log("[cpu] dispatch EIINT (direct vector) for IRQ %d\n", env->exception_cause&0x1ff);
+                //qemu_log("[cpu] exception priority=%d\n", env->exception_priority);
+                /* Direct vector. */
+                if (env->EBV_flag) 
+                    direct_vector_ba = env->systemRegs[BANK_ID_BASIC_1][EBASE_IDX1];
+                else
+                    direct_vector_ba = env->systemRegs[BANK_ID_BASIC_1][RBASE_IDX1]; 
+                //qemu_log("[cpu] Direct vector Base Address = 0x%08x\n", direct_vector_ba);
+               
+                /* Is RINT bit set ? */
+                if (direct_vector_ba & 1)
+                {
+                    //qemu_log("[cpu] RINT bit set\n");
+                    /* Reduced vector (one handler for any priority). */
+                    env->pc = (direct_vector_ba & 0xFFFFFF00) + 0x100; 
+                }
+                else
+                {
+                    //qemu_log("[cpu] RINT bit NOT set\n");
+                    /* One handler per priority level. */
+                    env->pc = (direct_vector_ba & 0xFFFFFF00) + 0x100 + (env->exception_priority<<4); 
+                }
+                //qemu_log("[cpu] PC=0x%08x\n", env->pc);
+            }
+            break;
+      }
+      
+#endif
+    cs->exception_index = EXCP_NONE; /* mark handled to qemu */
+}
diff --git a/qemu/target/rh850/helper.h b/qemu/target/rh850/helper.h
new file mode 100644
index 0000000000..24c9fa5865
--- /dev/null
+++ b/qemu/target/rh850/helper.h
@@ -0,0 +1,157 @@
+DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64)
+DEF_HELPER_6(uc_traceopcode, void, ptr, i64, i64, i32, ptr, i64)
+DEF_HELPER_1(uc_rh850_exit, void, env)
+
+/* Exceptions */
+DEF_HELPER_2(raise_exception, noreturn, env, i32)
+DEF_HELPER_3(raise_exception_with_cause, noreturn, env, i32, i32)
+
+
+/* Floating Point - rounding mode */
+DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
+
+/* Floating Point - fused */
+DEF_HELPER_FLAGS_4(fmadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
+DEF_HELPER_FLAGS_4(fmadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
+DEF_HELPER_FLAGS_4(fmsub_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
+DEF_HELPER_FLAGS_4(fmsub_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
+DEF_HELPER_FLAGS_4(fnmsub_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
+DEF_HELPER_FLAGS_4(fnmsub_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
+DEF_HELPER_FLAGS_4(fnmadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
+DEF_HELPER_FLAGS_4(fnmadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
+
+/* Floating Point - Single Precision */
+DEF_HELPER_FLAGS_2(f32_is_normal, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(f32_is_zero_or_normal, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(f32_is_infinity, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_1(f_sync_fflags, TCG_CALL_NO_RWG, void, env)
+
+DEF_HELPER_FLAGS_3(fadd_s, TCG_CALL_NO_RWG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fsub_s, TCG_CALL_NO_RWG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fmul_s, TCG_CALL_NO_RWG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fmax_s, TCG_CALL_NO_RWG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fmin_s, TCG_CALL_NO_RWG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fdiv_s, TCG_CALL_NO_RWG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_2(fabs_s, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(fneg_s, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(ftrnc_sw, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(fceil_sw, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(ffloor_sw, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(fcvt_sw, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(ftrnc_suw, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(fceil_suw, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(ffloor_suw, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(fcvt_suw, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(fcvt_ws, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(fcvt_ls, TCG_CALL_NO_RWG, i32, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_hs, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(fcvt_sh, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(fcvt_uws, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(fcvt_uls, TCG_CALL_NO_RWG, i32, env, i64)
+DEF_HELPER_FLAGS_2(ftrnc_sl, TCG_CALL_NO_RWG, i64, env, i32)
+DEF_HELPER_FLAGS_2(fceil_sl, TCG_CALL_NO_RWG, i64, env, i32)
+DEF_HELPER_FLAGS_2(ffloor_sl, TCG_CALL_NO_RWG, i64, env, i32)
+DEF_HELPER_FLAGS_2(fcvt_sl, TCG_CALL_NO_RWG, i64, env, i32)
+DEF_HELPER_FLAGS_2(ftrnc_sul, TCG_CALL_NO_RWG, i64, env, i32)
+DEF_HELPER_FLAGS_2(fceil_sul, TCG_CALL_NO_RWG, i64, env, i32)
+DEF_HELPER_FLAGS_2(ffloor_sul, TCG_CALL_NO_RWG, i64, env, i32)
+DEF_HELPER_FLAGS_2(fcvt_sul, TCG_CALL_NO_RWG, i64, env, i32)
+DEF_HELPER_FLAGS_2(fsqrt_s, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(frecip_s, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(frsqrt_s, TCG_CALL_NO_RWG, i32, env, i32)
+
+DEF_HELPER_FLAGS_2(f_is_nan_s, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_3(fle_s, TCG_CALL_NO_RWG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(flt_s, TCG_CALL_NO_RWG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(feq_s, TCG_CALL_NO_RWG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_2(fcvt_w_s, TCG_CALL_NO_RWG, tl, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_wu_s, TCG_CALL_NO_RWG, tl, env, i64)
+
+DEF_HELPER_FLAGS_4(fmaf_s, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
+DEF_HELPER_FLAGS_4(fmsf_s, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
+DEF_HELPER_FLAGS_4(fnmaf_s, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
+DEF_HELPER_FLAGS_4(fnmsf_s, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
+
+
+
+
+#if defined(TARGET_RH85064)
+DEF_HELPER_FLAGS_2(fcvt_l_s, TCG_CALL_NO_RWG, tl, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_lu_s, TCG_CALL_NO_RWG, tl, env, i64)
+#endif
+DEF_HELPER_FLAGS_2(fcvt_s_w, TCG_CALL_NO_RWG, i64, env, tl)
+DEF_HELPER_FLAGS_2(fcvt_s_wu, TCG_CALL_NO_RWG, i64, env, tl)
+#if defined(TARGET_RH85064)
+DEF_HELPER_FLAGS_2(fcvt_s_l, TCG_CALL_NO_RWG, i64, env, tl)
+DEF_HELPER_FLAGS_2(fcvt_s_lu, TCG_CALL_NO_RWG, i64, env, tl)
+#endif
+DEF_HELPER_FLAGS_1(fclass_s, TCG_CALL_NO_RWG_SE, tl, i64)
+
+/* Floating Point - Double Precision */
+DEF_HELPER_FLAGS_3(fadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(fsub_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(fmul_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(fmax_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(fmin_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(fdiv_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_2(fabs_d, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fneg_d, TCG_CALL_NO_RWG, i64, env, i64)
+
+DEF_HELPER_FLAGS_2(ftrnc_dw, TCG_CALL_NO_RWG, i32, env, i64)
+DEF_HELPER_FLAGS_2(fceil_dw, TCG_CALL_NO_RWG, i32, env, i64)
+DEF_HELPER_FLAGS_2(ffloor_dw, TCG_CALL_NO_RWG, i32, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_dw, TCG_CALL_NO_RWG, i32, env, i64)
+DEF_HELPER_FLAGS_2(ftrnc_duw, TCG_CALL_NO_RWG, i32, env, i64)
+DEF_HELPER_FLAGS_2(fceil_duw, TCG_CALL_NO_RWG, i32, env, i64)
+DEF_HELPER_FLAGS_2(ffloor_duw, TCG_CALL_NO_RWG, i32, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_duw, TCG_CALL_NO_RWG, i32, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_wd, TCG_CALL_NO_RWG, i64, env, i32)
+DEF_HELPER_FLAGS_2(fcvt_ld, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_sd, TCG_CALL_NO_RWG, i64, env, i32)
+DEF_HELPER_FLAGS_2(fcvt_uwd, TCG_CALL_NO_RWG, i64, env, i32)
+DEF_HELPER_FLAGS_2(fcvt_uld, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(ftrnc_dl, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fceil_dl, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(ffloor_dl, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_dl, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(ftrnc_dul, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fceil_dul, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(ffloor_dul, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_dul, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fsqrt_d, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(frecip_d, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(frsqrt_d, TCG_CALL_NO_RWG, i64, env, i64)
+
+DEF_HELPER_FLAGS_2(f_is_nan_d, TCG_CALL_NO_RWG, i32, env, i64)
+DEF_HELPER_FLAGS_3(fle_d, TCG_CALL_NO_RWG, i32, env, i64, i64)
+DEF_HELPER_FLAGS_3(flt_d, TCG_CALL_NO_RWG, i32, env, i64, i64)
+DEF_HELPER_FLAGS_3(feq_d, TCG_CALL_NO_RWG, i32, env, i64, i64)
+
+
+
+DEF_HELPER_FLAGS_2(fcvt_s_d, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_d_s, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_w_d, TCG_CALL_NO_RWG, tl, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_wu_d, TCG_CALL_NO_RWG, tl, env, i64)
+#if defined(TARGET_RH85064)
+DEF_HELPER_FLAGS_2(fcvt_l_d, TCG_CALL_NO_RWG, tl, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_lu_d, TCG_CALL_NO_RWG, tl, env, i64)
+#endif
+DEF_HELPER_FLAGS_2(fcvt_d_w, TCG_CALL_NO_RWG, i64, env, tl)
+DEF_HELPER_FLAGS_2(fcvt_d_wu, TCG_CALL_NO_RWG, i64, env, tl)
+#if defined(TARGET_RH85064)
+DEF_HELPER_FLAGS_2(fcvt_d_l, TCG_CALL_NO_RWG, i64, env, tl)
+DEF_HELPER_FLAGS_2(fcvt_d_lu, TCG_CALL_NO_RWG, i64, env, tl)
+#endif
+DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64)
+
+/* Special functions */
+//DEF_HELPER_3(csrrw, tl, env, tl, tl)
+//DEF_HELPER_4(csrrs, tl, env, tl, tl, tl)
+//DEF_HELPER_4(csrrc, tl, env, tl, tl, tl)
+#ifndef CONFIG_USER_ONLY
+//DEF_HELPER_2(sret, tl, env, tl)
+//DEF_HELPER_2(mret, tl, env, tl)
+//DEF_HELPER_1(wfi, void, env)
+DEF_HELPER_1(tlb_flush, void, env)
+#endif
diff --git a/qemu/target/rh850/instmap.h b/qemu/target/rh850/instmap.h
new file mode 100644
index 0000000000..2cbf2aed2f
--- /dev/null
+++ b/qemu/target/rh850/instmap.h
@@ -0,0 +1,624 @@
+/*
+ * RH850 emulation for qemu: Instruction decode helpers
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _RH850_INSTMAP_H
+#define _RH850_INSTMAP_H
+
+enum{
+	/*SIGNED INT*/
+	COND_RH850_BGE = 1110,
+	COND_RH850_BGT = 1111,
+	COND_RH850_BLE = 0111,
+	COND_RH850_BLT = 0110,
+	/*UNSIGNED INT*/
+	COND_RH850_BH = 1011,
+	COND_RH850_BL = 0001,
+	COND_RH850_BNH = 0011,
+	COND_RH850_BNL = 1001,
+	/*COMMON*/
+	COND_RH850_BE = 0010,
+	COND_RH850_BNE = 1010,
+	/*OTHERS*/
+	COND_RH850_BC = 0001,
+	COND_RH850_BF = 1010,
+	COND_RH850_BN = 0100,
+	COND_RH850_BNC = 1001,
+	COND_RH850_BNV = 1000,
+	COND_RH850_BNZ = 1010,
+	COND_RH850_BP = 1100,
+	COND_RH850_BR = 0101,
+	COND_RH850_BSA = 1101,
+	COND_RH850_BT = 0010,
+	COND_RH850_BV = 0000,
+	COND_RH850_BZ = 0010,
+};
+
+#define MASK_OP_MAJOR(op)  (op & (0x3F << 5)) // the major opcode in rh850 is at bits 10-5
+enum {
+	/* FORMAT I */						// unique opcodes and grouped instructions
+	OPC_RH850_16bit_0 = (0x0 << 5),		// group with opcode 0x0 (nop, synci, synce, syncm, syncp, mov)
+	OPC_RH850_NOT_reg1_reg2 	= (0x1 << 5),
+	OPC_RH850_16bit_2 = (0x2 << 5),		// group with opcode 0x2 (rie, switch, divh, fetrap)
+	OPC_RH850_16bit_3 = (0x3 << 5), 	// group with opcode 0x3 (jmp,sld.bu,sld.hu)
+	OPC_RH850_16bit_4 = (0x4 << 5),		// group with opcode 0x4 (zyb, satsub)
+	OPC_RH850_16bit_5 = (0x5 << 5),		// group with opcode 0x5 (sxb, satsub)
+	OPC_RH850_16bit_6 = (0x6 << 5),		// group with opcode 0x6 (zyh, satadd)
+	OPC_RH850_16bit_7 = (0x7 << 5),		// group with opcode 0x7 (sxh, mulh)
+	OPC_RH850_OR_reg1_reg2 	= (0x8 << 5),
+	OPC_RH850_XOR_reg1_reg2 	= (0x9 << 5),
+	OPC_RH850_AND_reg1_reg2 	= (0xA << 5),
+	OPC_RH850_TST_reg1_reg2 	= (0xB << 5),
+	OPC_RH850_SUBR_reg1_reg2 	= (0xC << 5),
+	OPC_RH850_SUB_reg1_reg2 	= (0xD << 5),
+	OPC_RH850_ADD_reg1_reg2 	= (0xE << 5),
+	OPC_RH850_CMP_reg1_reg2 = (0xF << 5),
+
+	/* FORMAT II */
+	OPC_RH850_16bit_16 = (0x10 << 5),	// group with opcode 0x10 (mov,callt)
+	OPC_RH850_16bit_17 = (0x11 << 5),	// group with opcode 0x11 (callt, satadd)
+	OPC_RH850_ADD_imm5_reg2= (0x12 << 5),   // group with opcode 0x12 (add)
+	OPC_RH850_CMP_imm5_reg2 = (0x13 << 5),	// group with opcode 0x13 (cmp)
+	OPC_RH850_SHR_imm5_reg2 = (0x14 << 5),
+	OPC_RH850_SAR_imm5_reg2 = (0x15 << 5),
+	OPC_RH850_SHL_imm5_reg2 = (0x16 << 5),
+	OPC_RH850_MULH_imm5_reg2 = (0x17 << 5),
+
+	/*FORMAT III */
+	OPC_RH850_BCOND = (0xB << 7), 	// different mask! (bits 10-7)
+
+	/* FORMAT IV */					// different mask! (bits 10-7)
+	OPC_RH850_16bit_SLDB = (0x6 << 5),
+	OPC_RH850_16bit_SLDH = (0x8 << 5),
+	OPC_RH850_16bit_IV10 = (0xA << 5), 		// group with opcode 0xA (sld.w,sst.w)
+	OPC_RH850_16bit_SSTB = (0x7 << 5),
+	OPC_RH850_16bit_SSTH = (0x9 << 5),
+
+	/* FORMAT VI */
+	OPC_RH850_ADDI_imm16_reg1_reg2	=	(0x30 << 5),
+	OPC_RH850_ANDI_imm16_reg1_reg2	=	(0x36 << 5),
+	OPC_RH850_MOVEA	=	(0x31 << 5),     	// this is also MOV 3, which is 48 bit
+	OPC_RH850_MOVHI_imm16_reg1_reg2	=	(0x32 << 5),
+	OPC_RH850_ORI_imm16_reg1_reg2	=	(0x34 << 5),
+	OPC_RH850_SATSUBI_imm16_reg1_reg2=	(0x33 << 5),
+	OPC_RH850_XORI_imm16_reg1_reg2	=	(0x35 << 5),
+
+
+	/* FORMAT VII */
+
+	OPC_RH850_LOOP	=	(0x37 << 5), 		//same as MULHI in format VI !!!!
+
+	OPC_RH850_LDB 	  = (0x38 << 5),
+	OPC_RH850_LDH_LDW = (0x39 << 5),
+	OPC_RH850_STB 	  = (0x3A << 5),
+	OPC_RH850_STH_STW = (0x3B << 5), 	//the store halfword and store word instructions differ on LSB displacement bit 16 (0=ST.H, 1=ST.W) (format VII)
+
+	OPC_RH850_ST_LD_0 = (0x3C << 5), 	//5 instructions share this opcode, sub-op bits 11-15 are 0, inst. differ in sub-op bits 16-19 (ST.B2=D, ST.W2=F) (format XIV)
+	OPC_RH850_ST_LD_1 = (0x3D << 5), 	//5 instructions share this opcode, sub-op bits 11-15 are 0, inst. differ in sub-op bits 16-19 (ST.DW=F, ST.H2=D) (format XIV)
+	//OPC_RH850_LDHU  = (0x3F << 5),	//bits 11-15 are not all 0
+
+	OPC_RH850_32bit_1 = (0x3F << 5),	// 111111
+
+
+
+
+	OPC_RH850_BIT_MANIPULATION_2	=	(0x3E << 5),
+
+	OPC_RH850_FORMAT_V_XIII = (0x1E << 6),
+
+
+	OPC_RH850_MULH1 = (0x7 << 5),
+	OPC_RH850_MULH2 = (0x17 << 5),
+
+
+};
+
+enum{
+	OPC_RH850_SET1_reg2_reg1	=	0,
+	OPC_RH850_NOT1_reg2_reg1	=	2,
+	OPC_RH850_CLR1_reg2_reg1	=	4,
+	OPC_RH850_TST1_reg2_reg1	=	6,
+};
+
+enum{
+	OPC_RH850_SET1_bit3_disp16_reg1	=	1,
+	OPC_RH850_NOT1_bit3_disp16_reg1	=	3,
+	OPC_RH850_CLR1_bit3_disp16_reg1	=	5,
+	OPC_RH850_TST1_bit3_disp16_reg1	=	7,
+};
+
+enum{
+	OPC_RH850_MOV_reg1_reg2		= 1,
+	OPC_RH850_MOV_imm5_reg2		= 2,
+	OPC_RH850_MOV_imm32_reg1	= 3,
+	OPC_RH850_MOVEA_imm16_reg1_reg2	= 4,
+};
+
+enum{
+	OPC_RH850_SATADD_reg1_reg2 		= 1,
+	OPC_RH850_SATADD_imm5_reg2 		= 2,
+	OPC_RH850_SATADD_reg1_reg2_reg3	= 3,
+	OPC_RH850_SATSUB_reg1_reg2		= 4,
+	OPC_RH850_SATSUB_reg1_reg2_reg3 = 5,
+	OPC_RH850_SATSUBR_reg1_reg2		= 6,
+};
+
+enum{
+	OPC_RH850_MUL_reg1_reg2_reg3	= 1,
+	OPC_RH850_MUL_imm9_reg2_reg3	= 2,
+	OPC_RH850_MULH_reg1_reg2		= 3,
+	//OPC_RH850_MULH_imm5_reg2		= 4,
+	OPC_RH850_MULHI_imm16_reg1_reg2	= 5,
+	OPC_RH850_MULU_reg1_reg2_reg3	= 8,
+	OPC_RH850_MULU_imm9_reg2_reg3	= 9,
+};
+
+enum{
+	OPC_RH850_ADF_cccc_reg1_reg2_reg3	= 10,
+	OPC_RH850_SBF_cccc_reg1_reg2_reg3	= 11,
+	OPC_RH850_DIVH_reg1_reg2			= 12,
+};
+
+enum{		//enum for gen_data_manipulation cases
+	OPC_RH850_SHR_reg1_reg2 		= 111,
+	OPC_RH850_SHR_reg1_reg2_reg3	= 222,
+	OPC_RH850_CMOV_cccc_reg1_reg2_reg3	= 333,
+	OPC_RH850_CMOV_cccc_imm5_reg2_reg3	= 444,
+	OPC_RH850_ROTL_reg1_reg2_reg3	= 445,
+	OPC_RH850_ROTL_imm5_reg2_reg3	= 446,
+	OPC_RH850_SAR_reg1_reg2			= 447,
+	OPC_RH850_SAR_reg1_reg2_reg3	= 448,
+	OPC_RH850_SASF_cccc_reg2		= 449,
+	OPC_RH850_SETF_cccc_reg2		= 450,
+	OPC_RH850_SHL_reg1_reg2			= 451,
+	OPC_RH850_SHL_reg1_reg2_reg3	= 453,
+	OPC_RH850_SXB_reg1				= 454,
+	OPC_RH850_SXH_reg1				= 455,
+	OPC_RH850_ZXB_reg1				= 456,
+	OPC_RH850_ZXH_reg1				= 457,
+
+
+
+};
+
+enum{
+	OPC_RH850_LDSR_reg2_regID_selID	= 1,
+	OPC_RH850_STSR_regID_reg2_selID = 2,
+	//check for unintentional matching
+	OPC_RH850_PREPARE_list12_imm5	= 12,
+	OPC_RH850_PREPARE_list12_imm5_sp	= 13,
+	OPC_RH850_RIE 					= 3,
+	OPC_RH850_CALLT_imm6			= 4,
+	OPC_RH850_CAXI_reg1_reg2_reg3	= 5,
+	OPC_RH850_DISPOSE_imm5_list12	= 7,
+	OPC_RH850_DISPOSE_imm5_list12_reg1 = 8,
+	OPC_RH850_FETRAP_vector4		= 15,
+	OPC_RH850_SWITCH_reg1			= 10,
+};
+
+enum{ // magic numbers for branch opcodes
+	OPC_RH850_JR_imm22			= 0,
+	OPC_RH850_JR_imm32			= 1,
+	OPC_RH850_JARL_disp22_reg2	= 2,
+	OPC_RH850_JARL_disp32_reg1	= 3, //48-bit
+	OPC_RH850_JARL_reg1_reg3	= 4,
+	OPC_RH850_JMP_reg1			= 5,
+	OPC_RH850_JMP_disp32_reg1	= 6,
+
+};
+
+
+#define MASK_OP_FORMAT_I_0(op)	(MASK_OP_MAJOR(op) | (op & (0x1F << 11)) | (op & (0x1F << 0)))
+enum {
+	OPC_RH850_NOP 	= OPC_RH850_16bit_0 | (0x0 << 11) | (0x0 << 0),
+	OPC_RH850_SYNCI = OPC_RH850_16bit_0 | (0x0 << 11) | (0x1C << 0),
+	OPC_RH850_SYNCE = OPC_RH850_16bit_0 | (0x0 << 11) | (0x1D << 0),
+	OPC_RH850_SYNCM = OPC_RH850_16bit_0 | (0x0 << 11) | (0x1E << 0),
+	OPC_RH850_SYNCP = OPC_RH850_16bit_0 | (0x0 << 11) | (0x1F << 0)
+};
+
+
+
+#define MASK_OP_ST_LD0(op)   (MASK_OP_MAJOR(op) | (op & (0x1F << 11)) | (op & (0xF << 16)))
+enum {
+
+	OPC_RH850_LDB2 	= OPC_RH850_ST_LD_0 | (0x00 << 11 ) | (0x5 << 16),
+	OPC_RH850_LDH2 	= OPC_RH850_ST_LD_0 | (0x00 << 11 ) | (0x7 << 16),
+	OPC_RH850_LDW2 	= OPC_RH850_ST_LD_0 | (0x00 << 11 ) | (0x9 << 16),
+	OPC_RH850_STB2 	= OPC_RH850_ST_LD_0 | (0x00 << 11 ) | (0xD << 16),		//sub-op bits 11-15 are 0, inst. differ in sub-op bits 16-19 (ST.B2=D, ST.W2=F) (format XIV)
+	OPC_RH850_STW2	= OPC_RH850_ST_LD_0 | (0x00 << 11 ) | (0xF << 16),
+
+};
+#define MASK_OP_ST_LD1(op)   (MASK_OP_MAJOR(op) | (op & (0x1F << 11)) | (op & (0xF << 16)))
+enum {
+
+	OPC_RH850_LDBU2 = OPC_RH850_ST_LD_1 | (0x00 << 11 ) | (0x5 << 16),
+	OPC_RH850_LDHU2 = OPC_RH850_ST_LD_1 | (0x00 << 11 ) | (0x7 << 16),
+	OPC_RH850_LDDW 	= OPC_RH850_ST_LD_1 | (0x00 << 11 ) | (0x9 << 16),
+	OPC_RH850_STDW 	= OPC_RH850_ST_LD_1 | (0x00 << 11 ) | (0xF << 16),
+	OPC_RH850_STH2 	= OPC_RH850_ST_LD_1 | (0x00 << 11 ) | (0xD << 16),
+};
+
+#define MASK_OP_32BIT_SUB(op)	(op & (0xF << 23))
+enum {
+	OPC_RH850_LDSR_RIE_SETF_STSR	=	(0x0 << 23),
+	OPC_RH850_FORMAT_IX				=	(0x1 << 23),	// 0001
+	OPC_RH850_FORMAT_X				=	(0x2 << 23),	// 0010
+	OPC_RH850_MUL_INSTS				=	(0x4 << 23),	// 0100 this is also for SASF
+	OPC_RH850_FORMAT_XI				=	(0x5 << 23),	// 0101
+	OPC_RH850_FORMAT_XII			=	(0x6 << 23),	// 0110
+	OPC_RH850_ADDIT_ARITH			=	(0x7 << 23),	// 0111
+	OPC_RH850_FORMAT_FI_CAT0		=   (0x8 << 23),	// 1000 used for floating-point instructions
+	OPC_RH850_FORMAT_FI_CAT1		= 	(0x9 << 23)		// 1001 used for specific FPU instructions
+};
+
+#define MASK_OP_FORMAT_IX(op) (op & (0x3 << 21))   //0001 on b26-b23
+enum {
+	OPC_RH850_BINS_0	= (0x0  << 21), //BINS0,SHR, SHR2
+	OPC_RH850_BINS_1	= (0x1  << 21), //BINS1,SAR,SAR2
+	OPC_RH850_BINS_2	= (0x2  << 21),	//BINS2,SHL, SHL2, ROTL, ROTL2
+	OPC_RH850_BIT_MANIPULATION		= (0x3  << 21),	//clr1, set, tst1, not1, caxi in format IX
+};
+
+#define MASK_OP_FORMAT_X(op) (op & (0xFFF << 11))	//0010 on b26-b23
+enum {
+	OPC_RH850_CTRET		= 	(0x880 << 11),
+	OPC_RH850_DI		= 	(0xC00 << 11),
+	OPC_RH850_EI		= 	(0XC10 << 11),
+	OPC_RH850_EIRET		= 	(0X900 << 11),
+	OPC_RH850_FERET		= 	(0X940 << 11),
+	OPC_RH850_HALT		= 	(0X400 << 11),
+	OPC_RH850_JARL3		= 	(0XC18 << 11),
+	OPC_RH850_SNOOZE	= 	(0x401 << 11),
+	OPC_RH850_SYSCALL	= 	(0xC1A << 11),
+	OPC_RH850_TRAP		= 	(0x000 << 11),
+	OPC_RH850_PREF		= 	(0xC1B << 11),
+	OPC_RH850_POPSP_rh_rt	= 	(0xC0C << 11),
+	OPC_RH850_PUSHSP_rh_rt	= 	(0xC08 << 11),
+	//don't forget CACHE
+	OPC_RH850_CLL	= 	(0xC1F << 11),
+
+};
+
+#define MASK_OP_FORMAT_XI(op) (op & (0x7F << 16))
+enum {
+	OPC_RH850_DIVH_reg1_reg2_reg3 	= 0x0,
+	OPC_RH850_DIVHU_reg1_reg2_reg3 	= 0x2,
+	OPC_RH850_DIV_reg1_reg2_reg3 	= 0x40,
+	OPC_RH850_DIVQ 	= 0x7C,
+	OPC_RH850_DIVQU	= 0x7E,
+	OPC_RH850_DIVU_reg1_reg2_reg3	= 0x42
+};
+
+#define MASK_OP_FORMAT_XII(op) (op & (0x3 << 17))
+enum {
+	OPC_RH850_BSW_reg2_reg3	= (0x0 << 0),
+	OPC_RH850_BSH_reg2_reg3 = (0x1 << 0),
+	OPC_RH850_HSW_reg2_reg3	= (0x2 << 0),
+	OPC_RH850_HSH_reg2_reg3	= (0x3 << 0),
+	// SCHOL, SCHOR, SCH1L, SCH1R
+	OPC_RH850_SCH0R_reg2_reg3	= (0x0 << 0),
+	OPC_RH850_SCH1R_reg2_reg3	= (0x1 << 0), //this is also STCW
+	OPC_RH850_SCH0L_reg2_reg3	= (0x2 << 0),
+	OPC_RH850_SCH1L_reg2_reg3	= (0x3 << 0),
+
+
+};
+
+#define MASK_ADDIT_ARITH_OP(op) (op & (0x3 << 21))
+enum {
+	OPC_RH850_SBF_SATSUB	= 0x0,
+	OPC_RH850_ADF_SATADD3	= 0x1,
+	OPC_RH850_MAC_reg1_reg2_reg3_reg4	= 0x2,
+	OPC_RH850_MACU_reg1_reg2_reg3_reg4	= 0x3,
+};
+
+/*
+ * FPU instruction format (F:I)
+ */
+
+enum {
+	FPU_TYPE_S,
+	FPU_TYPE_D,
+	FPU_TYPE_LS,
+	FPU_TYPE_LD,
+	FPU_TYPE_DL,
+	FPU_TYPE_SD,
+	FPU_TYPE_SL,
+	FPU_TYPE_DW,
+	FPU_TYPE_WD,
+	FPU_TYPE_HS,
+	FPU_TYPE_SH,
+	FPU_TYPE_SW,
+	FPU_TYPE_WS,
+	FPU_TYPE_DUW,
+	FPU_TYPE_SUW,
+	FPU_TYPE_UWD,
+	FPU_TYPE_UWS,
+	FPU_TYPE_ULD,
+	FPU_TYPE_ULS,
+	FPU_TYPE_SUL,
+	FPU_TYPE_DUL
+};
+
+enum {
+	FPU_OP_ABS,
+	FPU_OP_ADD,
+	FPU_OP_CEIL,
+	FPU_OP_CVT,
+	FPU_OP_DIV,
+	FPU_OP_FLOOR,
+	FPU_OP_CMOV,
+	FPU_OP_CMP,
+	FPU_OP_MAX,
+	FPU_OP_MIN,
+	FPU_OP_MUL,
+	FPU_OP_NEG,
+	FPU_OP_RECIP,
+	FPU_OP_RSQRT,
+	FPU_OP_SQRT,
+	FPU_OP_SUB,
+	FPU_OP_TRNC
+};
+
+#define MASK_OP_FORMAT_FI(op) (op & (0x7F << 16))
+enum {
+	OPC_RH850_FPU_CMOV_S_OR_TRFSR	=   0x00 << 16,
+	OPC_RH850_FPU_CMOV_D	=   0x10 << 16,
+	OPC_RH850_FPU_CMP_S		=   0x20 << 16,
+	OPC_RH850_FPU_CMP_D		=   0x30 << 16,
+	OPC_RH850_FPU_GROUP_CMPD=	0x30 << 16,
+	OPC_RH850_FPU_GROUP_SW	=	0x40 << 16,
+	OPC_RH850_FPU_GROUP_DS	=	0x42 << 16,
+	OPC_RH850_FPU_GROUP_SL	=	0x44 << 16,
+	OPC_RH850_FPU_GROUP_ABSS	=	0x48 << 16,
+	OPC_RH850_FPU_GROUP_S	=	0x4E << 16,
+	OPC_RH850_FPU_GROUP_DW	=	0x50 << 16,
+	OPC_RH850_FPU_GROUP_DD	= 	0x52 << 16,
+	OPC_RH850_FPU_GROUP_DL	=	0x54 << 16,
+	OPC_RH850_FPU_GROUP_ABSD	=	0x58 << 16,
+	OPC_RH850_FPU_GROUP_D	=	0x5E << 16,
+	OPC_RH850_FPU_ADDF_S	=	0x60 << 16,
+	OPC_RH850_FPU_SUBF_S	=	0x62 << 16,
+	OPC_RH850_FPU_MULF_S	=	0x64 << 16,
+	OPC_RH850_FPU_MAXF_S	=	0x68 << 16,
+	OPC_RH850_FPU_MINF_S	=	0x6A << 16,
+	OPC_RH850_FPU_DIVF_S	=	0x6E << 16,
+	OPC_RH850_FPU_ADDF_D	=	0x70 << 16,
+	OPC_RH850_FPU_SUBF_D	=	0x72 << 16,
+	OPC_RH850_FPU_MULF_D	=	0x74 << 16,
+	OPC_RH850_FPU_MAXF_D	=	0x78 << 16,
+	OPC_RH850_FPU_MINF_D	=	0x7A << 16,
+	OPC_RH850_FPU_DIVF_D	=	0x7E << 16
+};
+
+/* OPC_RH850_FPU_GROUP_CMPS/D, variant defined by cond reg3. */
+enum {
+	OPC_RH850_FPU_CMPS_F = 0x20,
+	OPC_RH850_FPU_CMPS_UN,
+	OPC_RH850_FPU_CMPS_EQ,
+	OPC_RH850_FPU_CMPS_UEQ,
+	OPC_RH850_FPU_CMPS_OLT,
+	OPC_RH850_FPU_CMPS_ULT,
+	OPC_RH850_FPU_CMPS_OLE,
+	OPC_RH850_FPU_CMPS_ULE,
+	OPC_RH850_FPU_CMPS_SF,
+	OPC_RH850_FPU_CMPS_NGLE,
+	OPC_RH850_FPU_CMPS_SEQ,
+	OPC_RH850_FPU_CMPS_NGL,
+	OPC_RH850_FPU_CMPS_LT,
+	OPC_RH850_FPU_CMPS_NGE,
+	OPC_RH850_FPU_CMPS_LE,
+	OPC_RH850_FPU_CMPS_NGT
+};
+
+/* OPC_RH850_FPU_GROUP_SW, variant defined by reg1 */
+enum {
+	OPC_RH850_FPU_TRNCF_SW=0x1,
+	OPC_RH850_FPU_CEILF_SW,
+	OPC_RH850_FPU_FLOORF_SW,
+	OPC_RH850_FPU_CVTF_SW,
+	OPC_RH850_FPU_TRNCF_SUW=0x11,
+	OPC_RH850_FPU_CEILF_SUW,
+	OPC_RH850_FPU_FLOORF_SUW,
+	OPC_RH850_FPU_CVTF_SUW=0x14
+};
+
+/* OPC_RH850_FPU_GROUP_DS, variant defined by reg1 */
+enum {
+	OPC_RH850_FPU_CVTF_WS=0x0,
+	OPC_RH850_FPU_CVTF_LS,
+	OPC_RH850_FPU_CVTF_HS,
+	OPC_RH850_FPU_CVTF_SH,
+	OPC_RH850_FPU_CVTF_UWS=0x10,
+	OPC_RH850_FPU_CVTF_ULS
+};
+
+/* OPC_RH850_FPU_GROUP_SL, variant defined by reg1 */
+enum {
+	OPC_RH850_FPU_TRNCF_SL	=	0x1,
+	OPC_RH850_FPU_CEILF_SL,
+	OPC_RH850_FPU_FLOORF_SL,
+	OPC_RH850_FPU_CVTF_SL,
+	OPC_RH850_FPU_TRNCF_SUL	=	0x11,
+	OPC_RH850_FPU_CEILF_SUL,
+	OPC_RH850_FPU_FLOORF_SUL,
+	OPC_RH850_FPU_CVTF_SUL
+};
+
+/* OPC_RH850_FPU_GROUP_ABSS, variant defined by reg1 */
+enum {
+	OPC_RH850_FPU_ABSF_S	=	0x0,
+	OPC_RH850_FPU_NEGF_S,
+};
+
+/* OPC_RH850_FPU_GROUP_S, variant defined by reg1 */
+enum {
+	OPC_RH850_FPU_SQRTF_S	=	0x0,
+	OPC_RH850_FPU_RECIPF_S,
+	OPC_RH850_FPU_RSQRTF_S
+};
+
+
+/* OPC_RH850_FPU_GROUP_DW, variant defined by reg1 */
+enum {
+	OPC_RH850_FPU_TRNCF_DW	=	0x1,
+	OPC_RH850_FPU_CEILF_DW,
+	OPC_RH850_FPU_FLOORF_DW,
+	OPC_RH850_FPU_CVTF_DW,
+	OPC_RH850_FPU_TRNCF_DUW	=	0x11,
+	OPC_RH850_FPU_CEILF_DUW,
+	OPC_RH850_FPU_FLOORF_DUW,
+	OPC_RH850_FPU_CVTF_DUW
+};
+
+/* OPC_RH850_FPU_GROUP_DD, variant defined by reg1 */
+enum {
+	OPC_RH850_FPU_CVTF_WD	=	0x00,
+	OPC_RH850_FPU_CVTF_LD,
+	OPC_RH850_FPU_CVTF_SD,
+	OPC_RH850_FPU_CVTF_UWD	=	0x10,
+	OPC_RH850_FPU_CVTF_ULD
+};
+
+/* OPC_RH850_FPU_GROUP_DL, variant defined by reg1 */
+enum {
+	OPC_RH850_FPU_TRNCF_DL	=	0x1,
+	OPC_RH850_FPU_CEILF_DL,
+	OPC_RH850_FPU_FLOORF_DL,
+	OPC_RH850_FPU_CVTF_DL,
+	OPC_RH850_FPU_TRNCF_DUL	=	0x11,
+	OPC_RH850_FPU_CEILF_DUL,
+	OPC_RH850_FPU_FLOORF_DUL,
+	OPC_RH850_FPU_CVTF_DUL
+};
+
+/* OPC_RH850_FPU_GROUP_ABSD, variant defined by reg1 */
+enum {
+	OPC_RH850_FPU_ABSF_D	=	0x0,
+	OPC_RH850_FPU_NEGF_D,
+};
+
+/* OPC_RH850_FPU_GROUP_D, variant defined by reg1 */
+enum {
+	OPC_RH850_FPU_SQRTF_D	=	0x0,
+	OPC_RH850_FPU_RECIPF_D,
+	OPC_RH850_FPU_RSQRTF_D
+};
+
+/* Format F:I with category=1 */
+enum {
+	OPC_RH850_FPU_FMAF_S = 0x60 << 16,
+	OPC_RH850_FPU_FMSF_S = 0x62 << 16,
+	OPC_RH850_FPU_FNMAF_S = 0x64 << 16,
+	OPC_RH850_FPU_FNMSF_S = 0x66 << 16
+};
+
+#define MASK_OP_FORMAT_V_FORMAT_XIII(op) (op & (0x1F << 6))
+
+
+enum {
+	operation_LDL_W = 0,
+	operation_STC_W = 1,
+	operation_CLL = 2,
+};
+
+
+
+//////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////
+
+
+#define GET_B_IMM(inst) ((extract32(inst, 8, 4) << 1) \
+                         | (extract32(inst, 25, 6) << 5) \
+                         | (extract32(inst, 7, 1) << 11) \
+                         | (sextract64(inst, 31, 1) << 12))
+
+#define GET_STORE_IMM(inst) ((extract32(inst, 7, 5)) \
+                             | (sextract64(inst, 25, 7) << 5))
+
+#define GET_JAL_IMM(inst) ((extract32(inst, 21, 10) << 1) \
+                           | (extract32(inst, 20, 1) << 11) \
+                           | (extract32(inst, 12, 8) << 12) \
+                           | (sextract64(inst, 31, 1) << 20))
+
+
+#define GET_RS1(inst)  extract32(inst, 0, 5)		//appropriate for RH850
+#define GET_RS2(inst)  extract32(inst, 11, 5)		//appropriate for RH850
+#define GET_RS3(inst)  extract32(inst, 27, 5)		//appropriate for RH850
+#define GET_DISP(inst) (extract32(inst, 20, 7) | (sextract32(inst, 32, 16) << 7 ) ) //b47-b32 + b26-b20
+
+
+#define GET_RM(inst)   extract32(inst, 12, 3)
+#define GET_RD(inst)   extract32(inst, 7, 5)
+#define GET_IMM(inst)  sextract64(inst, 20, 12)
+#define GET_IMM_32(inst)	sextract64(inst, 16, 32)
+
+/* RVC decoding macros */
+#define GET_C_IMM(inst)             (extract32(inst, 2, 5) \
+                                    | (sextract64(inst, 12, 1) << 5))
+#define GET_C_ZIMM(inst)            (extract32(inst, 2, 5) \
+                                    | (extract32(inst, 12, 1) << 5))
+#define GET_C_ADDI4SPN_IMM(inst)    ((extract32(inst, 6, 1) << 2) \
+                                    | (extract32(inst, 5, 1) << 3) \
+                                    | (extract32(inst, 11, 2) << 4) \
+                                    | (extract32(inst, 7, 4) << 6))
+#define GET_C_ADDI16SP_IMM(inst)    ((extract32(inst, 6, 1) << 4) \
+                                    | (extract32(inst, 2, 1) << 5) \
+                                    | (extract32(inst, 5, 1) << 6) \
+                                    | (extract32(inst, 3, 2) << 7) \
+                                    | (sextract64(inst, 12, 1) << 9))
+#define GET_C_LWSP_IMM(inst)        ((extract32(inst, 4, 3) << 2) \
+                                    | (extract32(inst, 12, 1) << 5) \
+                                    | (extract32(inst, 2, 2) << 6))
+#define GET_C_LDSP_IMM(inst)        ((extract32(inst, 5, 2) << 3) \
+                                    | (extract32(inst, 12, 1) << 5) \
+                                    | (extract32(inst, 2, 3) << 6))
+#define GET_C_SWSP_IMM(inst)        ((extract32(inst, 9, 4) << 2) \
+                                    | (extract32(inst, 7, 2) << 6))
+#define GET_C_SDSP_IMM(inst)        ((extract32(inst, 10, 3) << 3) \
+                                    | (extract32(inst, 7, 3) << 6))
+#define GET_C_LW_IMM(inst)          ((extract32(inst, 6, 1) << 2) \
+                                    | (extract32(inst, 10, 3) << 3) \
+                                    | (extract32(inst, 5, 1) << 6))
+#define GET_C_LD_IMM(inst)          ((extract32(inst, 10, 3) << 3) \
+                                    | (extract32(inst, 5, 2) << 6))
+#define GET_C_J_IMM(inst)           ((extract32(inst, 3, 3) << 1) \
+                                    | (extract32(inst, 11, 1) << 4) \
+                                    | (extract32(inst, 2, 1) << 5) \
+                                    | (extract32(inst, 7, 1) << 6) \
+                                    | (extract32(inst, 6, 1) << 7) \
+                                    | (extract32(inst, 9, 2) << 8) \
+                                    | (extract32(inst, 8, 1) << 10) \
+                                    | (sextract64(inst, 12, 1) << 11))
+#define GET_C_B_IMM(inst)           ((extract32(inst, 3, 2) << 1) \
+                                    | (extract32(inst, 10, 2) << 3) \
+                                    | (extract32(inst, 2, 1) << 5) \
+                                    | (extract32(inst, 5, 2) << 6) \
+                                    | (sextract64(inst, 12, 1) << 8))
+#define GET_C_SIMM3(inst)           extract32(inst, 10, 3)
+#define GET_C_RD(inst)              GET_RD(inst)
+#define GET_C_RS1(inst)             GET_RD(inst)
+#define GET_C_RS2(inst)             extract32(inst, 2, 5)
+#define GET_C_RS1S(inst)            (8 + extract32(inst, 7, 3))
+#define GET_C_RS2S(inst)            (8 + extract32(inst, 2, 3))
+
+#endif /* _RH850_INSTMAP_H */
\ No newline at end of file
diff --git a/qemu/target/rh850/op_helper.c b/qemu/target/rh850/op_helper.c
new file mode 100644
index 0000000000..36e272e7a0
--- /dev/null
+++ b/qemu/target/rh850/op_helper.c
@@ -0,0 +1,89 @@
+/*
+ * RH850 Emulation Helpers for QEMU.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2017-2018 SiFive, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+
+/* Exceptions processing helpers */
+void QEMU_NORETURN do_raise_exception_err(CPURH850State *env,
+                                          uint32_t exception, uintptr_t pc)
+{
+    CPUState *cs = CPU(rh850_env_get_cpu(env));
+    qemu_log_mask(CPU_LOG_INT, "%s: %d\n", __func__, exception);
+    cs->exception_index = exception;
+    cpu_loop_exit_restore(cs, pc);
+}
+
+void QEMU_NORETURN do_raise_exception_err_with_cause(CPURH850State *env,
+                                          uint32_t exception, uint32_t cause, uintptr_t pc)
+{
+    CPUState *cs = CPU(rh850_env_get_cpu(env));
+    //qemu_log_mask(CPU_LOG_INT, "%s: %d\n", __func__, exception);
+    cs->exception_index = exception;
+    env->exception_cause = cause; 
+    cpu_loop_exit_restore(cs, pc);
+}
+
+
+void helper_raise_exception(CPURH850State *env, uint32_t exception)
+{
+    do_raise_exception_err(env, exception, 0);
+}
+
+void helper_raise_exception_with_cause(CPURH850State *env, uint32_t exception, uint32_t cause)
+{
+    do_raise_exception_err_with_cause(env, exception, cause, 0);
+}
+
+target_ulong csr_read_helper(CPURH850State *env, target_ulong csrno)
+{
+    return 0;
+}
+
+#ifndef CONFIG_USER_ONLY
+
+/* iothread_mutex must be held */
+void rh850_set_local_interrupt(RH850CPU *cpu, target_ulong mask, int value)
+{
+}
+
+void rh850_set_mode(CPURH850State *env, target_ulong newpriv)
+{
+}
+
+void helper_tlb_flush(CPURH850State *env)
+{
+    RH850CPU *cpu = rh850_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
+    tlb_flush(cs);
+}
+
+void helper_uc_rh850_exit(CPURH850State *env)
+{
+    CPUState *cs = CPU(env);
+
+    cs->exception_index = EXCP_HLT;
+    cs->halted = 1;
+    cpu_loop_exit(cs);
+}
+
+#endif /* !CONFIG_USER_ONLY */
diff --git a/qemu/target/rh850/pmp.c b/qemu/target/rh850/pmp.c
new file mode 100644
index 0000000000..8f98659d3a
--- /dev/null
+++ b/qemu/target/rh850/pmp.c
@@ -0,0 +1,379 @@
+/*
+ * QEMU RH850 PMP (Physical Memory Protection)
+ *
+ * Author: Daire McNamara, daire.mcnamara@emdalo.com
+ *         Ivan Griffin, ivan.griffin@emdalo.com
+ *
+ * This provides a RH850 Physical Memory Protection implementation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * PMP (Physical Memory Protection) is as-of-yet unused and needs testing.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "cpu.h"
+#include "qemu-common.h"
+
+#ifndef CONFIG_USER_ONLY
+
+#define RH850_DEBUG_PMP 0
+#define PMP_DEBUG(fmt, ...)                                                    \
+    do {                                                                       \
+        if (RH850_DEBUG_PMP) {                                                 \
+            qemu_log_mask(LOG_TRACE, "%s: " fmt "\n", __func__, ##__VA_ARGS__);\
+        }                                                                      \
+    } while (0)
+
+static void pmp_write_cfg(CPURH850State *env, uint32_t addr_index,
+    uint8_t val);
+static uint8_t pmp_read_cfg(CPURH850State *env, uint32_t addr_index);
+static void pmp_update_rule(CPURH850State *env, uint32_t pmp_index);
+
+/*
+ * Accessor method to extract address matching type 'a field' from cfg reg
+ */
+static inline uint8_t pmp_get_a_field(uint8_t cfg)
+{
+    uint8_t a = cfg >> 3;
+    return a & 0x3;
+}
+
+/*
+ * Check whether a PMP is locked or not.
+ */
+static inline int pmp_is_locked(CPURH850State *env, uint32_t pmp_index)
+{
+
+    if (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_LOCK) {
+        return 1;
+    }
+
+    /* Top PMP has no 'next' to check */
+    if ((pmp_index + 1u) >= MAX_RH850_PMPS) {
+        return 0;
+    }
+
+    /* In TOR mode, need to check the lock bit of the next pmp
+     * (if there is a next)
+     */
+    const uint8_t a_field =
+        pmp_get_a_field(env->pmp_state.pmp[pmp_index + 1].cfg_reg);
+    if ((env->pmp_state.pmp[pmp_index + 1u].cfg_reg & PMP_LOCK) &&
+         (PMP_AMATCH_TOR == a_field)) {
+        return 1;
+    }
+
+    return 0;
+}
+
+/*
+ * Count the number of active rules.
+ */
+static inline uint32_t pmp_get_num_rules(CPURH850State *env)
+{
+     return env->pmp_state.num_rules;
+}
+
+/*
+ * Accessor to get the cfg reg for a specific PMP/HART
+ */
+static inline uint8_t pmp_read_cfg(CPURH850State *env, uint32_t pmp_index)
+{
+    if (pmp_index < MAX_RH850_PMPS) {
+        return env->pmp_state.pmp[pmp_index].cfg_reg;
+    }
+
+    return 0;
+}
+
+
+/*
+ * Accessor to set the cfg reg for a specific PMP/HART
+ * Bounds checks and relevant lock bit.
+ */
+static void pmp_write_cfg(CPURH850State *env, uint32_t pmp_index, uint8_t val)
+{
+    if (pmp_index < MAX_RH850_PMPS) {
+        if (!pmp_is_locked(env, pmp_index)) {
+            env->pmp_state.pmp[pmp_index].cfg_reg = val;
+            pmp_update_rule(env, pmp_index);
+        } else {
+            PMP_DEBUG("ignoring write - locked");
+        }
+    } else {
+        PMP_DEBUG("ignoring write - out of bounds");
+    }
+}
+
+static void pmp_decode_napot(target_ulong a, target_ulong *sa, target_ulong *ea)
+{
+    /*
+       aaaa...aaa0   8-byte NAPOT range
+       aaaa...aa01   16-byte NAPOT range
+       aaaa...a011   32-byte NAPOT range
+       ...
+       aa01...1111   2^XLEN-byte NAPOT range
+       a011...1111   2^(XLEN+1)-byte NAPOT range
+       0111...1111   2^(XLEN+2)-byte NAPOT range
+       1111...1111   Reserved
+    */
+    if (a == -1) {
+        *sa = 0u;
+        *ea = -1;
+        return;
+    } else {
+        target_ulong t1 = ctz64(~a);
+        target_ulong base = (a & ~(((target_ulong)1 << t1) - 1)) << 3;
+        target_ulong range = ((target_ulong)1 << (t1 + 3)) - 1;
+        *sa = base;
+        *ea = base + range;
+    }
+}
+
+
+/* Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
+ *   end address values.
+ *   This function is called relatively infrequently whereas the check that
+ *   an address is within a pmp rule is called often, so optimise that one
+ */
+static void pmp_update_rule(CPURH850State *env, uint32_t pmp_index)
+{
+    int i;
+
+    env->pmp_state.num_rules = 0;
+
+    uint8_t this_cfg = env->pmp_state.pmp[pmp_index].cfg_reg;
+    target_ulong this_addr = env->pmp_state.pmp[pmp_index].addr_reg;
+    target_ulong prev_addr = 0u;
+    target_ulong sa = 0u;
+    target_ulong ea = 0u;
+
+    if (pmp_index >= 1u) {
+        prev_addr = env->pmp_state.pmp[pmp_index - 1].addr_reg;
+    }
+
+    switch (pmp_get_a_field(this_cfg)) {
+    case PMP_AMATCH_OFF:
+        sa = 0u;
+        ea = -1;
+        break;
+
+    case PMP_AMATCH_TOR:
+        sa = prev_addr << 2; /* shift up from [xx:0] to [xx+2:2] */
+        ea = (this_addr << 2) - 1u;
+        break;
+
+    case PMP_AMATCH_NA4:
+        sa = this_addr << 2; /* shift up from [xx:0] to [xx+2:2] */
+        ea = (this_addr + 4u) - 1u;
+        break;
+
+    case PMP_AMATCH_NAPOT:
+        pmp_decode_napot(this_addr, &sa, &ea);
+        break;
+
+    default:
+        sa = 0u;
+        ea = 0u;
+        break;
+    }
+
+    env->pmp_state.addr[pmp_index].sa = sa;
+    env->pmp_state.addr[pmp_index].ea = ea;
+
+    for (i = 0; i < MAX_RH850_PMPS; i++) {
+        const uint8_t a_field =
+            pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
+        if (PMP_AMATCH_OFF != a_field) {
+            env->pmp_state.num_rules++;
+        }
+    }
+}
+
+static int pmp_is_in_range(CPURH850State *env, int pmp_index, target_ulong addr)
+{
+    int result = 0;
+
+    if ((addr >= env->pmp_state.addr[pmp_index].sa)
+        && (addr <= env->pmp_state.addr[pmp_index].ea)) {
+        result = 1;
+    } else {
+        result = 0;
+    }
+
+    return result;
+}
+
+
+/*
+ * Public Interface
+ */
+
+/*
+ * Check if the address has required RWX privs to complete desired operation
+ */
+bool pmp_hart_has_privs(CPURH850State *env, target_ulong addr,
+    target_ulong size, pmp_priv_t privs)
+{
+    int i = 0;
+    int ret = -1;
+    target_ulong s = 0;
+    target_ulong e = 0;
+    pmp_priv_t allowed_privs = 0;
+
+    /* Short cut if no rules */
+    if (0 == pmp_get_num_rules(env)) {
+        return true;
+    }
+
+    /* 1.10 draft priv spec states there is an implicit order
+         from low to high */
+    for (i = 0; i < MAX_RH850_PMPS; i++) {
+        s = pmp_is_in_range(env, i, addr);
+        e = pmp_is_in_range(env, i, addr + size);
+
+        /* partially inside */
+        if ((s + e) == 1) {
+            PMP_DEBUG("pmp violation - access is partially inside");
+            ret = 0;
+            break;
+        }
+
+        /* fully inside */
+        const uint8_t a_field =
+            pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
+        if ((s + e) == 2) {
+            if (PMP_AMATCH_OFF == a_field) {
+                return 1;
+            }
+
+            allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
+            if ((env->priv != PRV_M) || pmp_is_locked(env, i)) {
+                allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
+            }
+
+            if ((privs & allowed_privs) == privs) {
+                ret = 1;
+                break;
+            } else {
+                ret = 0;
+                break;
+            }
+        }
+    }
+
+    /* No rule matched */
+    if (ret == -1) {
+        if (env->priv == PRV_M) {
+            ret = 1; /* Privileged spec v1.10 states if no PMP entry matches an
+                      * M-Mode access, the access succeeds */
+        } else {
+            ret = 0; /* Other modes are not allowed to succeed if they don't
+                      * match a rule, but there are rules.  We've checked for
+                      * no rule earlier in this function. */
+        }
+    }
+
+    return ret == 1 ? true : false;
+}
+
+
+/*
+ * Handle a write to a pmpcfg CSP
+ */
+void pmpcfg_csr_write(CPURH850State *env, uint32_t reg_index,
+    target_ulong val)
+{
+    int i;
+    uint8_t cfg_val;
+
+    PMP_DEBUG("hart " TARGET_FMT_ld ": reg%d, val: 0x" TARGET_FMT_lx,
+        env->mhartid, reg_index, val);
+
+    if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
+        PMP_DEBUG("ignoring write - incorrect address");
+        return;
+    }
+
+    for (i = 0; i < sizeof(target_ulong); i++) {
+        cfg_val = (val >> 8 * i)  & 0xff;
+        pmp_write_cfg(env, (reg_index * sizeof(target_ulong)) + i,
+            cfg_val);
+    }
+}
+
+
+/*
+ * Handle a read from a pmpcfg CSP
+ */
+target_ulong pmpcfg_csr_read(CPURH850State *env, uint32_t reg_index)
+{
+    int i;
+    target_ulong cfg_val = 0;
+    uint8_t val = 0;
+
+    for (i = 0; i < sizeof(target_ulong); i++) {
+        val = pmp_read_cfg(env, (reg_index * sizeof(target_ulong)) + i);
+        cfg_val |= (val << (i * 8));
+    }
+
+    PMP_DEBUG("hart " TARGET_FMT_ld ": reg%d, val: 0x" TARGET_FMT_lx,
+        env->mhartid, reg_index, cfg_val);
+
+    return cfg_val;
+}
+
+
+/*
+ * Handle a write to a pmpaddr CSP
+ */
+void pmpaddr_csr_write(CPURH850State *env, uint32_t addr_index,
+    target_ulong val)
+{
+    PMP_DEBUG("hart " TARGET_FMT_ld ": addr%d, val: 0x" TARGET_FMT_lx,
+        env->mhartid, addr_index, val);
+
+    if (addr_index < MAX_RH850_PMPS) {
+        if (!pmp_is_locked(env, addr_index)) {
+            env->pmp_state.pmp[addr_index].addr_reg = val;
+            pmp_update_rule(env, addr_index);
+        } else {
+            PMP_DEBUG("ignoring write - locked");
+        }
+    } else {
+        PMP_DEBUG("ignoring write - out of bounds");
+    }
+}
+
+
+/*
+ * Handle a read from a pmpaddr CSP
+ */
+target_ulong pmpaddr_csr_read(CPURH850State *env, uint32_t addr_index)
+{
+    PMP_DEBUG("hart " TARGET_FMT_ld ": addr%d, val: 0x" TARGET_FMT_lx,
+        env->mhartid, addr_index,
+        env->pmp_state.pmp[addr_index].addr_reg);
+    if (addr_index < MAX_RH850_PMPS) {
+        return env->pmp_state.pmp[addr_index].addr_reg;
+    } else {
+        PMP_DEBUG("ignoring read - out of bounds");
+        return 0;
+    }
+}
+
+#endif
diff --git a/qemu/target/rh850/pmp.h b/qemu/target/rh850/pmp.h
new file mode 100644
index 0000000000..e6e43e8241
--- /dev/null
+++ b/qemu/target/rh850/pmp.h
@@ -0,0 +1,64 @@
+/*
+ * QEMU RH850 PMP (Physical Memory Protection)
+ *
+ * Author: Daire McNamara, daire.mcnamara@emdalo.com
+ *         Ivan Griffin, ivan.griffin@emdalo.com
+ *
+ * This provides a RH850 Physical Memory Protection interface
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _RH850_PMP_H_
+#define _RH850_PMP_H_
+
+typedef enum {
+    PMP_READ  = 1 << 0,
+    PMP_WRITE = 1 << 1,
+    PMP_EXEC  = 1 << 2,
+    PMP_LOCK  = 1 << 7
+} pmp_priv_t;
+
+typedef enum {
+    PMP_AMATCH_OFF,  /* Null (off)                            */
+    PMP_AMATCH_TOR,  /* Top of Range                          */
+    PMP_AMATCH_NA4,  /* Naturally aligned four-byte region    */
+    PMP_AMATCH_NAPOT /* Naturally aligned power-of-two region */
+} pmp_am_t;
+
+typedef struct {
+    target_ulong addr_reg;
+    uint8_t  cfg_reg;
+} pmp_entry_t;
+
+typedef struct {
+    target_ulong sa;
+    target_ulong ea;
+} pmp_addr_t;
+
+typedef struct {
+    pmp_entry_t pmp[MAX_RH850_PMPS];
+    pmp_addr_t  addr[MAX_RH850_PMPS];
+    uint32_t num_rules;
+} pmp_table_t;
+
+void pmpcfg_csr_write(CPURH850State *env, uint32_t reg_index,
+    target_ulong val);
+target_ulong pmpcfg_csr_read(CPURH850State *env, uint32_t reg_index);
+void pmpaddr_csr_write(CPURH850State *env, uint32_t addr_index,
+    target_ulong val);
+target_ulong pmpaddr_csr_read(CPURH850State *env, uint32_t addr_index);
+bool pmp_hart_has_privs(CPURH850State *env, target_ulong addr,
+    target_ulong size, pmp_priv_t priv);
+
+#endif
diff --git a/qemu/target/rh850/register_indices.h b/qemu/target/rh850/register_indices.h
new file mode 100644
index 0000000000..20fcea8cae
--- /dev/null
+++ b/qemu/target/rh850/register_indices.h
@@ -0,0 +1,63 @@
+/*
+ * register_indices.h
+ *
+ *  Created on: Jun 18, 2018
+ *
+ */
+
+#ifndef TARGET_RH850_REGISTER_INDICES_H_
+#define TARGET_RH850_REGISTER_INDICES_H_
+
+
+// BANK ID 0, sys basic regs
+#define EIPC_IDX     0
+#define EIPSW_IDX    1
+#define FEPC_IDX     2
+#define FEPSW_IDX    3
+#define PSW_IDX	 	 5	//program status word
+// sysFpuRegs indices
+#define FPSR_IDX     6   //floating-point configuration/status   <---write the bit defines
+#define FPEPC_IDX    7   //floating point exception PC
+#define FPST_IDX     8
+#define FPCC_IDX     9
+#define FPCFG_IDX   10
+#define FPEC_IDX    11
+
+#define EIIC_IDX	13	//EI level exception cause
+#define FEIC_IDX	14	//FI level exception cause
+#define CTPC_IDX    16
+#define CTPSW_IDX   17
+#define CTBP_IDX    20
+#define EIWR_IDX    28
+#define FEWR_IDX    29
+#define BSEL_IDX    31
+
+// BANK ID 1, sys basic regs
+#define MCFG0_IDX1	0	//machine configuration
+#define RBASE_IDX1	2	//reset vector base address (if psw.ebv==0, this is also exception vector)
+#define EBASE_IDX1	3	//exception handler vector address
+#define INTBP_IDX1  4
+#define MCTL_IDX1   5	//CPU control
+#define PID_IDX1    6   //processor ID
+#define SCCFG_IDX1  11  // SYSCALL config
+#define SCBP_IDX1   12  // SYSCALL base pointer
+
+// BANK ID 2, sys basic regs
+#define HTCFG0_IDX2	0	//thread configuration
+#define MEA_IDX2	6	//memory error address (when misaligned or MPU)
+#define ASID_IDX2	7	//memory error address (when misaligned or MPU)
+#define MEI_IDX2	8	//memory error info (info about instruction that caused exception)
+
+// BANK ID 1, 2 sysInterruptRegs indices
+#define FPIPR_IDX1  7
+#define ISPR_IDX2   10
+#define PMR_IDX2    11
+#define ICSR_IDX2	12	//interrupt control status register
+#define INTCFG_IDX2	13	//interrupt function setting
+
+
+// BANK ID 5, 6, 7 system MPU regs indices
+#define MPM_IDX5	0	//memory protection operation mode
+
+
+#endif /* TARGET_RH850_REGISTER_INDICES_H_ */
diff --git a/qemu/target/rh850/translate.c b/qemu/target/rh850/translate.c
new file mode 100644
index 0000000000..7081656c95
--- /dev/null
+++ b/qemu/target/rh850/translate.c
@@ -0,0 +1,5190 @@
+/*
+ * RH850 emulation for qemu: main translation routines.
+ *
+ * Copyright (c) 2018 iSYSTEM Labs d.o.o.
+ * Copyright (c) 2023 Quarkslab
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "tcg/tcg-op.h"
+#include "tcg/tcg-op-gvec.h"
+#include "qemu/log.h"
+#include "qemu/host-utils.h"
+#include "exec/cpu_ldst.h"
+#include "exec/gen-icount.h"
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
+#include "exec/translator.h"
+
+#include "instmap.h"
+
+#include "unicorn/platform.h"
+#include "uc_priv.h"
+#include "translate.h"
+#include "fpu_translate.h"
+
+/*
+ * Unicorn: Special disas state for exiting in the middle of tb.
+ */
+
+/* We are not using a goto_tb (for whatever reason), but have updated
+   the PC (for whatever reason), so there's no need to do it again on
+   exiting the TB.  */
+#define DISAS_PC_UPDATED        DISAS_TARGET_0
+
+/* We have emitted one or more goto_tb.  No fixup required.  */
+#define DISAS_GOTO_TB           DISAS_TARGET_1
+
+/* We have updated the PC and CC values.  */
+#define DISAS_PC_CC_UPDATED     DISAS_TARGET_2
+
+/* We are exiting the TB, but have neither emitted a goto_tb, nor
+   updated the PC for the next instruction to be executed.  */
+#define DISAS_PC_STALE          DISAS_TARGET_3
+
+/* We are exiting the TB to the main loop.  */
+#define DISAS_PC_STALE_NOCHAIN  DISAS_TARGET_4
+
+#define DISAS_UNICORN_HALT DISAS_TARGET_11
+
+/* global register indices */
+static TCGv cpu_gpr[NUM_GP_REGS];
+static TCGv cpu_pc;
+static TCGv cpu_sysRegs[NUM_SYS_REG_BANKS][MAX_SYS_REGS_IN_BANK];
+// static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
+static TCGv cpu_sysDatabuffRegs[1], cpu_LLbit, cpu_LLAddress;
+static TCGv load_res;
+static TCGv load_val;
+
+// PSW register flags. These are for temporary use only during
+// calculations. Before usage they should be set from PSW and
+// stored back to PSW after changes.
+// TODO: since PSW as a register is rarely used - only when ld/str sys reg and
+// on some branches (TRAP, ...) it makes sense to compose/decompose PSW
+// on these occcasions and not have PSW stored in registers below.
+TCGv_i32 cpu_ZF, cpu_SF, cpu_OVF, cpu_CYF, cpu_SATF, cpu_ID, cpu_EP, cpu_NP,
+		cpu_EBV, cpu_CU0, cpu_CU1, cpu_CU2, cpu_UM;
+
+
+/** Const, RH850 does not have MMU. */
+const int MEM_IDX = 0;
+
+/* is_jmp field values */
+#define DISAS_INDIRECT_JUMP                 DISAS_TARGET_0 /* only pc was modified dynamically */
+#define DISAS_EXIT_TB                       DISAS_TARGET_1 /* cpu state was modified dynamically */
+#define DISAS_TB_EXIT_ALREADY_GENERATED     DISAS_TARGET_2
+#define CASE_OP_32_64(X)                    case X
+
+/* Possible conditions for tests. */
+enum {
+	V_COND 		= 0,		/* OV = 1 */
+	C_COND 		= 1,		/* CY = 1 */
+	Z_COND 		= 2,		/* Z = 1 */
+	NH_COND 	= 3,		/* (CY or Z) = 1 */
+	S_COND		= 4,		/* S = 1 */
+	T_COND		= 5,		/* Always */
+	LT_COND		= 6,		/* (S xor OV) = 1 */
+	LE_COND 	= 7,		/* ((S xor OV) or Z) = 1 */
+
+	NV_COND 	= 8,		/* OV = 0 */
+	NC_COND 	= 9,		/* CY = 0 */
+	NZ_COND 	= 10,		/* Z = 0 */
+	H_COND 		= 11,		/* (CY or Z) = 0 */
+	NS_COND		= 12,		/* S = 0 */
+	SA_COND		= 13,		/* SAT = 1 */
+	GE_COND		= 14,		/* (S xor OV) = 0 */
+	GT_COND 	= 15,		/* ((S xor OV) or Z) = 0 */
+};
+
+// Enumeration for Cache operations.
+enum {
+	CHBII = 0x0,
+	CIBII = 0x20,
+	CFALI = 0x40,
+	CISTI = 0x60,
+	CILDI = 0x61,
+	CLL = 0x7e,
+};
+
+enum {
+	OPC_RH850_BINS = 123456,
+};
+
+
+static void gen_exception_debug(DisasContext *dc)
+{
+    TCGContext *tcg_ctx = dc->uc->tcg_ctx;
+
+    TCGv_i32 helper_tmp = tcg_const_i32(tcg_ctx, EXCP_DEBUG);
+    gen_helper_raise_exception(tcg_ctx, tcg_ctx->cpu_env, helper_tmp);
+    tcg_temp_free_i32(tcg_ctx, helper_tmp);
+
+    dc->base.is_jmp = DISAS_TB_EXIT_ALREADY_GENERATED;
+}
+
+static void gen_exception_halt(DisasContext *dc)
+{
+    TCGContext *tcg_ctx = dc->uc->tcg_ctx;
+
+    TCGv_i32 helper_tmp = tcg_const_i32(tcg_ctx, EXCP_HLT);
+    gen_helper_raise_exception(tcg_ctx, tcg_ctx->cpu_env, helper_tmp);
+    tcg_temp_free_i32(tcg_ctx, helper_tmp);
+
+    dc->base.is_jmp = DISAS_TB_EXIT_ALREADY_GENERATED;
+}
+
+
+static void gen_goto_tb_imm(DisasContext *ctx, int n, target_ulong dest)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+    if (unlikely(ctx->base.singlestep_enabled)) {
+        tcg_gen_movi_tl(tcg_ctx, cpu_pc, dest);
+        gen_exception_debug(ctx);
+    } else {
+        tcg_gen_goto_tb(tcg_ctx, n);
+        tcg_gen_movi_tl(tcg_ctx, cpu_pc, dest);
+        tcg_gen_exit_tb(tcg_ctx, ctx->base.tb, n);
+    }
+}
+
+
+/* Wrapper for getting reg values - need to check of reg is zero since
+ * cpu_gpr[0] is not actually allocated
+ */
+void gen_get_gpr(TCGContext *tcg_ctx, TCGv t, int reg_num)
+{
+    if (reg_num == 0) {
+        tcg_gen_movi_tl(tcg_ctx, t, 0);
+    } else {
+        tcg_gen_mov_tl(tcg_ctx, t, cpu_gpr[reg_num]);
+    }
+
+}
+
+
+/* Wrapper for setting system register values. */
+
+void gen_set_spr(TCGContext *tcg_ctx, int bank_id, int reg_id, TCGv t)
+{
+    tcg_gen_mov_tl(tcg_ctx, cpu_sysRegs[bank_id][reg_id], t);
+}
+
+/* Wrapper for gettint sysreg values. */
+void gen_get_spr(TCGContext *tcg_ctx, int bank_id, int reg_id, TCGv t)
+{
+    tcg_gen_mov_tl(tcg_ctx, t, cpu_sysRegs[bank_id][reg_id]);
+}
+
+/* Wrapper for setting reg values - need to check of reg is zero since
+ * cpu_gpr[0] is not actually allocated. this is more for safety purposes,
+ * since we usually avoid calling the OP_TYPE_gen function if we see a write to
+ * $zero
+ */
+void gen_set_gpr(TCGContext *tcg_ctx, int reg_num_dst, TCGv t)
+{
+    if (reg_num_dst != 0) {
+        tcg_gen_mov_tl(tcg_ctx, cpu_gpr[reg_num_dst], t);
+    }
+}
+
+
+/**
+ * gen_goto_tb_rl() is a customized version of gen_goto_tb() that is able to
+ * move PC into a specified register before updating PC. V850e3 JARL/JR insts.
+ * work this way :).
+ **/
+
+static void gen_goto_tb_rl(DisasContext *ctx, int n, int reg, int insn_size, uint32_t dest)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+    TCGv reg_value = tcg_temp_new_i32(tcg_ctx);
+
+    if (unlikely(ctx->base.singlestep_enabled))
+    {
+
+        /* GR[reg] <- PC + insn_size */
+        tcg_gen_movi_i32(tcg_ctx, reg_value, ctx->pc);
+        tcg_gen_addi_i32(tcg_ctx, reg_value, reg_value, insn_size);
+        gen_set_gpr(tcg_ctx, reg, reg_value);
+
+        /* PC <- dest */
+        tcg_gen_movi_i32(tcg_ctx, cpu_pc, dest);
+
+        tcg_temp_free_i32(tcg_ctx, reg_value);
+
+        /* Generate exception. */
+        gen_exception_debug(ctx);
+    }
+    else
+    {
+        tcg_gen_goto_tb(tcg_ctx, n);
+
+        /* GR[reg] <- PC + insn_size */
+        tcg_gen_movi_i32(tcg_ctx, reg_value, ctx->pc);
+        tcg_gen_addi_i32(tcg_ctx, reg_value, reg_value, insn_size);
+        gen_set_gpr(tcg_ctx, reg, reg_value);
+
+        /* PC <- dest */
+        tcg_gen_movi_i32(tcg_ctx, cpu_pc, dest);
+
+        tcg_temp_free_i32(tcg_ctx, reg_value);
+
+        tcg_gen_exit_tb(tcg_ctx, ctx->base.tb, n);
+    }
+}
+
+
+static inline void tcgv_to_flags(TCGContext *tcg_ctx, TCGv reg)
+{
+    TCGv temp = tcg_temp_new_i32(tcg_ctx);
+    tcg_gen_mov_i32(tcg_ctx, temp, reg);
+    tcg_gen_andi_i32(tcg_ctx, cpu_ZF, temp, 0x1);
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_SF, temp, 0x1);
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_OVF, temp, 0x1);
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_CYF, temp, 0x1);
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_SATF, temp, 0x1);
+
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_ID, temp, 0x1);
+
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_EP, temp, 0x1);
+
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_NP, temp, 0x1);
+
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x8);
+    tcg_gen_andi_i32(tcg_ctx, cpu_EBV, temp, 0x1);
+
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_CU0, temp, 0x1);
+
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_CU1, temp, 0x1);
+
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_CU2, temp, 0x1);
+
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x12);
+    tcg_gen_andi_i32(tcg_ctx, cpu_UM, temp, 0x1);
+
+    tcg_temp_free(tcg_ctx, temp);
+}
+
+
+static void tcgv_to_flags_z_cy_ov_s_sat(TCGContext *tcg_ctx, TCGv reg)
+{
+    TCGv temp = tcg_temp_new_i32(tcg_ctx);
+    tcg_gen_mov_i32(tcg_ctx, temp, reg);
+    tcg_gen_andi_i32(tcg_ctx, cpu_ZF, temp, 0x1);
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_SF, temp, 0x1);
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_OVF, temp, 0x1);
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_CYF, temp, 0x1);
+    tcg_gen_shri_i32(tcg_ctx, temp, temp, 0x1);
+    tcg_gen_andi_i32(tcg_ctx, cpu_SATF, temp, 0x1);
+    tcg_temp_free(tcg_ctx, temp);
+}
+
+
+static void flags_to_tcgv_id_ep_np_ebv_cu_um(TCGContext *tcg_ctx, TCGv reg)
+{
+    // Set flags in PSW to 0 so we can OR with new state
+    tcg_gen_andi_i32(tcg_ctx, reg, reg, 0xbff87f1f);
+
+    TCGv temp = tcg_temp_new_i32(tcg_ctx);
+
+    tcg_gen_shli_i32(tcg_ctx, temp, cpu_ID, 0x5);
+    tcg_gen_or_i32(tcg_ctx, reg, reg,temp);
+
+    tcg_gen_shli_i32(tcg_ctx, temp, cpu_EP, 0x6);
+    tcg_gen_or_i32(tcg_ctx, reg, reg,temp);
+
+    tcg_gen_shli_i32(tcg_ctx, temp, cpu_NP, 0x7);
+    tcg_gen_or_i32(tcg_ctx, reg, reg,temp);
+
+    tcg_gen_shli_i32(tcg_ctx, temp, cpu_EBV, 0xF);
+    tcg_gen_or_i32(tcg_ctx, reg, reg,temp);
+
+    tcg_gen_shli_i32(tcg_ctx, temp, cpu_CU0, 0x10);
+    tcg_gen_or_i32(tcg_ctx, reg, reg,temp);
+
+    tcg_gen_shli_i32(tcg_ctx, temp, cpu_CU1, 0x11);
+    tcg_gen_or_i32(tcg_ctx, reg, reg,temp);
+
+    tcg_gen_shli_i32(tcg_ctx, temp, cpu_CU2, 0x12);
+    tcg_gen_or_i32(tcg_ctx, reg, reg,temp);
+
+    tcg_gen_shli_i32(tcg_ctx, temp, cpu_UM, 0x1E);
+    tcg_gen_or_i32(tcg_ctx, reg, reg,temp);
+
+    tcg_temp_free(tcg_ctx, temp);
+}
+
+
+static void flags_to_tcgv_z_cy_ov_s_sat(TCGContext *tcg_ctx, TCGv reg)
+{
+    // update psw register, first reset flags before ORing new values
+    tcg_gen_andi_i32(tcg_ctx, reg, reg, 0xffffffe0);
+    TCGv temp = tcg_temp_new_i32(tcg_ctx);
+    tcg_gen_or_i32(tcg_ctx, reg, reg, cpu_ZF);
+    tcg_gen_shli_i32(tcg_ctx, temp, cpu_SF, 0x1);
+    tcg_gen_or_i32(tcg_ctx, reg,reg,temp);
+    tcg_gen_shli_i32(tcg_ctx, temp, cpu_OVF, 0x2);
+    tcg_gen_or_i32(tcg_ctx, reg,reg,temp);
+    tcg_gen_shli_i32(tcg_ctx, temp, cpu_CYF, 0x3);
+    tcg_gen_or_i32(tcg_ctx, reg,reg,temp);
+    tcg_gen_shli_i32(tcg_ctx, temp, cpu_SATF, 0x4);
+    tcg_gen_or_i32(tcg_ctx, reg,reg,temp);
+    tcg_temp_free(tcg_ctx, temp);
+}
+
+
+static void flags_to_tcgv(TCGContext *tcg_ctx, TCGv reg)
+{
+    flags_to_tcgv_z_cy_ov_s_sat(tcg_ctx, reg);
+    flags_to_tcgv_id_ep_np_ebv_cu_um(tcg_ctx, reg);
+}
+
+
+static TCGv condition_satisfied(TCGContext *tcg_ctx, int cond)
+{
+	TCGv condResult = tcg_temp_new_i32(tcg_ctx);
+	tcg_gen_movi_i32(tcg_ctx, condResult, 0x0);
+
+	switch(cond) {
+		case GE_COND:
+			tcg_gen_xor_i32(tcg_ctx, condResult, cpu_SF, cpu_OVF);
+			tcg_gen_not_i32(tcg_ctx, condResult, condResult);
+			tcg_gen_andi_i32(tcg_ctx, condResult, condResult, 0x1);
+			break;
+		case GT_COND:
+			tcg_gen_xor_i32(tcg_ctx, condResult, cpu_SF, cpu_OVF);
+			tcg_gen_or_i32(tcg_ctx, condResult, condResult, cpu_ZF);
+			tcg_gen_not_i32(tcg_ctx, condResult, condResult);
+			tcg_gen_andi_i32(tcg_ctx, condResult, condResult, 0x1);
+			break;
+		case LE_COND:
+			tcg_gen_xor_i32(tcg_ctx, condResult, cpu_SF, cpu_OVF);
+			tcg_gen_or_i32(tcg_ctx, condResult, condResult, cpu_ZF);
+			break;
+		case LT_COND:
+			tcg_gen_xor_i32(tcg_ctx, condResult, cpu_SF, cpu_OVF);
+			break;
+
+		case H_COND:
+			tcg_gen_or_i32(tcg_ctx, condResult, cpu_CYF, cpu_ZF);
+			tcg_gen_not_i32(tcg_ctx, condResult, condResult);
+			tcg_gen_andi_i32(tcg_ctx, condResult, condResult, 0x1);
+			break;
+		case NH_COND:
+			tcg_gen_or_i32(tcg_ctx, condResult, cpu_CYF, cpu_ZF);
+			break;
+
+		case NS_COND:
+			tcg_gen_not_i32(tcg_ctx, condResult, cpu_SF);
+			tcg_gen_andi_i32(tcg_ctx, condResult, condResult, 0x1);
+			break;
+
+		case S_COND:
+		    tcg_gen_mov_i32(tcg_ctx, condResult, cpu_SF);
+		    break;
+
+		case C_COND:
+            tcg_gen_mov_i32(tcg_ctx, condResult, cpu_CYF);
+            break;
+
+		case NC_COND:
+			tcg_gen_not_i32(tcg_ctx, condResult, cpu_CYF);
+			tcg_gen_andi_i32(tcg_ctx, condResult, condResult, 0x1);
+			break;
+		case NV_COND:
+			tcg_gen_not_i32(tcg_ctx, condResult, cpu_OVF);
+			tcg_gen_andi_i32(tcg_ctx, condResult, condResult, 0x1);
+			break;
+		case NZ_COND:
+			tcg_gen_not_i32(tcg_ctx, condResult, cpu_ZF);
+			tcg_gen_andi_i32(tcg_ctx, condResult, condResult, 0x1);
+			break;
+
+		case SA_COND:
+            tcg_gen_mov_i32(tcg_ctx, condResult, cpu_SATF);
+            break;
+		case T_COND:
+			tcg_gen_movi_i32(tcg_ctx, condResult, 0x1);
+			break;
+		case V_COND:
+            tcg_gen_mov_i32(tcg_ctx, condResult, cpu_OVF);
+            break;
+		case Z_COND:
+            tcg_gen_mov_i32(tcg_ctx, condResult, cpu_ZF);
+            break;
+	}
+
+	return condResult;
+}
+
+static void gen_flags_on_add(TCGContext *tcg_ctx, TCGv_i32 t0, TCGv_i32 t1)
+{
+	TCGLabel *cont;
+	TCGLabel *end;
+
+    TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
+    tcg_gen_movi_i32(tcg_ctx, tmp, 0);
+    // 'add2(rl, rh, al, ah, bl, bh) creates 64-bit values and adds them:
+    // [CYF : SF] = [tmp : t0] + [tmp : t1]
+    // While CYF is 0 or 1, SF bit 15 contains sign, so it
+    // must be shifted 31 bits to the right later.
+    tcg_gen_add2_i32(tcg_ctx, cpu_SF, cpu_CYF, t0, tmp, t1, tmp);
+    tcg_gen_mov_i32(tcg_ctx, cpu_ZF, cpu_SF);
+
+    tcg_gen_xor_i32(tcg_ctx, cpu_OVF, cpu_SF, t0);
+    tcg_gen_xor_i32(tcg_ctx, tmp, t0, t1);
+    tcg_gen_andc_i32(tcg_ctx, cpu_OVF, cpu_OVF, tmp);
+
+    tcg_gen_shri_i32(tcg_ctx, cpu_SF, cpu_SF, 0x1f);
+    tcg_gen_shri_i32(tcg_ctx, cpu_OVF, cpu_OVF, 0x1f);
+
+    tcg_temp_free_i32(tcg_ctx, tmp);
+
+    cont = gen_new_label(tcg_ctx);
+	end = gen_new_label(tcg_ctx);
+
+	tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, 0x0, cont);
+	tcg_gen_movi_i32(tcg_ctx, cpu_ZF, 0x1);
+	tcg_gen_br(tcg_ctx, end);
+
+	gen_set_label(tcg_ctx, cont);
+	tcg_gen_movi_i32(tcg_ctx, cpu_ZF, 0x0);
+
+	gen_set_label(tcg_ctx, end);
+}
+
+
+static void gen_satadd_CC(TCGContext *tcg_ctx, TCGv_i32 t0, TCGv_i32 t1, TCGv_i32 result)
+{
+	TCGLabel *cont;
+	TCGLabel *end;
+
+    TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
+    tcg_gen_movi_i32(tcg_ctx, tmp, 0);
+    tcg_gen_add2_i32(tcg_ctx, cpu_SF, cpu_CYF, t0, tmp, t1, tmp);
+    tcg_gen_mov_i32(tcg_ctx, cpu_ZF, cpu_SF);
+    tcg_gen_xor_i32(tcg_ctx, cpu_OVF, cpu_SF, t0);
+    tcg_gen_xor_i32(tcg_ctx, tmp, t0, t1);
+    tcg_gen_andc_i32(tcg_ctx, cpu_OVF, cpu_OVF, tmp);
+
+    tcg_gen_shri_i32(tcg_ctx, cpu_SF, result, 0x1f);
+    tcg_gen_shri_i32(tcg_ctx, cpu_OVF, cpu_OVF, 0x1f);
+    tcg_temp_free_i32(tcg_ctx, tmp);
+
+    cont = gen_new_label(tcg_ctx);
+	end = gen_new_label(tcg_ctx);
+
+	tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, 0x0, cont);
+	tcg_gen_movi_i32(tcg_ctx, cpu_ZF, 0x1);
+	tcg_gen_br(tcg_ctx, end);
+
+	gen_set_label(tcg_ctx, cont);
+	tcg_gen_movi_i32(tcg_ctx, cpu_ZF, 0x0);
+
+	gen_set_label(tcg_ctx, end);
+}
+
+static void gen_flags_on_sub(TCGContext *tcg_ctx, TCGv_i32 t0, TCGv_i32 t1)
+{
+    tcg_gen_sub_tl(tcg_ctx, cpu_SF, t0, t1);
+    tcg_gen_setcond_i32(tcg_ctx, TCG_COND_GTU, cpu_CYF, t1, t0);
+    tcg_gen_setcond_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, t0, t1);
+    tcg_gen_xor_i32(tcg_ctx, cpu_OVF, cpu_SF, t0);
+    TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
+    tcg_gen_xor_i32(tcg_ctx, tmp, t0, t1);
+    tcg_gen_and_i32(tcg_ctx, cpu_OVF, cpu_OVF, tmp);
+
+    tcg_gen_shri_i32(tcg_ctx, cpu_SF, cpu_SF, 0x1f);
+	tcg_gen_shri_i32(tcg_ctx, cpu_OVF, cpu_OVF, 0x1f);
+    tcg_temp_free_i32(tcg_ctx, tmp);
+}
+
+static void gen_satsub_CC(TCGContext *tcg_ctx, TCGv_i32 t0, TCGv_i32 t1, TCGv_i32 result)
+{
+	TCGLabel *cont;
+	TCGLabel *end;
+
+    TCGv_i32 tmp;
+    tcg_gen_sub_tl(tcg_ctx, cpu_SF, t0, t1);
+
+    tcg_gen_mov_i32(tcg_ctx, cpu_ZF, cpu_SF);
+    tcg_gen_setcond_i32(tcg_ctx, TCG_COND_GTU, cpu_CYF, t1, t0);
+    tcg_gen_xor_i32(tcg_ctx, cpu_OVF, cpu_SF, t0);
+    tmp = tcg_temp_new_i32(tcg_ctx);
+    tcg_gen_xor_i32(tcg_ctx, tmp, t0, t1);
+    tcg_gen_and_i32(tcg_ctx, cpu_OVF, cpu_OVF, tmp);
+
+    tcg_gen_shri_i32(tcg_ctx, cpu_SF, result, 0x1f);
+	tcg_gen_shri_i32(tcg_ctx, cpu_OVF, cpu_OVF, 0x1f);
+    tcg_temp_free_i32(tcg_ctx, tmp);
+
+    cont = gen_new_label(tcg_ctx);
+	end = gen_new_label(tcg_ctx);
+
+	tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, 0x0, cont);
+	tcg_gen_movi_i32(tcg_ctx, cpu_ZF, 0x1);
+	tcg_gen_br(tcg_ctx, end);
+
+	gen_set_label(tcg_ctx, cont);
+	tcg_gen_movi_i32(tcg_ctx, cpu_ZF, 0x0);
+
+	gen_set_label(tcg_ctx, end);
+}
+
+static void gen_logic_CC(TCGContext *tcg_ctx, TCGv_i32 result){
+
+	TCGLabel *cont;
+	TCGLabel *end;
+
+	tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+	tcg_gen_shri_i32(tcg_ctx, cpu_SF, result, 0x1f);
+
+	cont = gen_new_label(tcg_ctx);
+	end = gen_new_label(tcg_ctx);
+
+	tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, result, 0x0, cont);
+	tcg_gen_movi_i32(tcg_ctx, cpu_ZF, 0x1);
+	tcg_gen_br(tcg_ctx, end);
+
+	gen_set_label(tcg_ctx, cont);
+	tcg_gen_movi_i32(tcg_ctx, cpu_ZF, 0x0);
+
+	gen_set_label(tcg_ctx, end);
+}
+
+
+static void gen_load(DisasContext *ctx, int memop, int rd, int rs1,
+		target_long imm, unsigned is_disp23)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+    TCGv t0 = tcg_temp_new(tcg_ctx);
+    TCGv t1 = tcg_temp_new(tcg_ctx);
+    TCGv tcg_imm = tcg_temp_new(tcg_ctx);
+    TCGv_i64 t1_64 = tcg_temp_new_i64(tcg_ctx);
+    TCGv t1_high = tcg_temp_new(tcg_ctx);
+
+    gen_get_gpr(tcg_ctx, t0, rs1);
+	tcg_gen_movi_i32(tcg_ctx, tcg_imm, imm);
+
+    if (!is_disp23)
+    	tcg_gen_ext16s_i32(tcg_ctx, tcg_imm, tcg_imm);
+    else {
+        tcg_gen_shli_i32(tcg_ctx, tcg_imm, tcg_imm, 9);
+        tcg_gen_sari_i32(tcg_ctx, tcg_imm, tcg_imm, 9);
+    }
+
+	tcg_gen_add_tl(tcg_ctx, t0, t0, tcg_imm);
+
+    if (memop == MO_TEQ) {
+        tcg_gen_qemu_ld_i64(tcg_ctx, t1_64, t0, MEM_IDX, memop);
+        tcg_gen_extrl_i64_i32(tcg_ctx, t1, t1_64);
+        tcg_gen_extrh_i64_i32(tcg_ctx, t1_high, t1_64);
+        gen_set_gpr(tcg_ctx, rd, t1);
+        gen_set_gpr(tcg_ctx, rd+1, t1_high);
+    }
+    else {
+    	tcg_gen_qemu_ld_tl(tcg_ctx, t1, t0, MEM_IDX, memop);
+        gen_set_gpr(tcg_ctx, rd, t1);
+    }
+
+    tcg_temp_free(tcg_ctx, t0);
+    tcg_temp_free(tcg_ctx, t1);
+    tcg_temp_free(tcg_ctx, tcg_imm);
+    tcg_temp_free_i64(tcg_ctx, t1_64);
+    tcg_temp_free(tcg_ctx, t1_high);
+}
+
+static void gen_store(DisasContext *ctx, int memop, int rs1, int rs2,
+        target_long imm, unsigned is_disp23)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+    TCGv t0 = tcg_temp_new(tcg_ctx);
+    TCGv dat = tcg_temp_new(tcg_ctx);
+    TCGv tcg_imm = tcg_temp_new(tcg_ctx);
+    TCGv dat_high = tcg_temp_new(tcg_ctx);
+    TCGv_i64 dat64 = tcg_temp_new_i64(tcg_ctx);
+
+    gen_get_gpr(tcg_ctx, t0, rs1);				// loading rs1 to t0
+    tcg_gen_movi_i32(tcg_ctx, tcg_imm, imm);
+
+    if (!is_disp23)
+    	tcg_gen_ext16s_i32(tcg_ctx, tcg_imm, tcg_imm);
+    else {
+        tcg_gen_shli_i32(tcg_ctx, tcg_imm, tcg_imm, 9);
+        tcg_gen_sari_i32(tcg_ctx, tcg_imm, tcg_imm, 9);
+    }
+
+    tcg_gen_add_tl(tcg_ctx, t0, t0, tcg_imm);	// adding displacement to t0
+
+    gen_get_gpr(tcg_ctx, dat, rs2);				// getting data from rs2
+
+    if (memop == MO_TEQ) {
+        gen_get_gpr(tcg_ctx, dat_high, rs2+1);
+        tcg_gen_concat_i32_i64(tcg_ctx, dat64, dat, dat_high);
+    	tcg_gen_qemu_st_i64(tcg_ctx, dat64, t0, MEM_IDX, memop);
+    }
+    else {
+    	tcg_gen_qemu_st_tl(tcg_ctx, dat, t0, MEM_IDX, memop);
+    }
+
+    // clear possible mutex
+	TCGLabel *l = gen_new_label(tcg_ctx);
+    tcg_gen_brcond_i32(tcg_ctx, TCG_COND_NE, t0, cpu_LLAddress, l);
+    tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, cpu_LLbit, 0x1, l);
+    tcg_gen_movi_i32(tcg_ctx, cpu_LLbit, 0);
+    gen_set_label(tcg_ctx, l);
+
+    tcg_temp_free(tcg_ctx, t0);
+    tcg_temp_free(tcg_ctx, dat);
+    tcg_temp_free(tcg_ctx, tcg_imm);
+    tcg_temp_free_i64(tcg_ctx, dat64);
+    tcg_temp_free(tcg_ctx, dat_high);
+}
+
+static void gen_mutual_exclusion(DisasContext *ctx, int rs3, int rs1, int operation)
+{
+	/* LDL.W, STC.W, CLL: Implement as described.
+	Add two additional global CPU registers called LLBit and LLAddress.
+	Set them with LDL.W, and reset them with STC.W.
+	If LLBit is not set or LLAddress does not match STC.W address, make STC.W fail.
+	CLL clears LLBit.
+	Since we do not implement multicore CPU emulation, this implementation should be OK. */
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+    if (operation == operation_LDL_W)
+    {
+        TCGv adr = tcg_temp_new(tcg_ctx);
+        TCGv dat = tcg_temp_new(tcg_ctx);
+
+        gen_get_gpr(tcg_ctx, adr, rs1);
+		tcg_gen_qemu_ld_tl(tcg_ctx, dat, adr, MEM_IDX, MO_TESL);
+		gen_set_gpr(tcg_ctx, rs3, dat);
+
+		tcg_temp_free(tcg_ctx, adr);
+		tcg_temp_free(tcg_ctx, dat);
+
+		tcg_gen_movi_i32(tcg_ctx, cpu_LLbit, 1);
+		tcg_gen_mov_i32(tcg_ctx, cpu_LLAddress, adr);
+    }
+    else if (operation == operation_STC_W)
+    {
+        TCGv adr = tcg_temp_local_new(tcg_ctx);
+        TCGv dat = tcg_temp_local_new(tcg_ctx);
+        TCGv token = tcg_temp_local_new(tcg_ctx);
+		TCGLabel *l_fail = gen_new_label(tcg_ctx);
+		TCGLabel *l_ok = gen_new_label(tcg_ctx);
+
+	    tcg_gen_mov_i32(tcg_ctx, token, cpu_LLbit);
+	    tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, token, 0x1, l_fail);
+        gen_get_gpr(tcg_ctx, adr, rs1);
+        gen_get_gpr(tcg_ctx, dat, rs3);
+	    tcg_gen_brcond_i32(tcg_ctx, TCG_COND_NE, adr, cpu_LLAddress, l_fail);
+        tcg_gen_qemu_st_tl(tcg_ctx, dat, adr, MEM_IDX, MO_TESL);
+	    tcg_gen_movi_i32(tcg_ctx, dat, 1);
+        tcg_gen_br(tcg_ctx, l_ok);
+
+	    gen_set_label(tcg_ctx, l_fail);
+        tcg_gen_movi_i32(tcg_ctx, dat, 0);
+	    gen_set_label(tcg_ctx, l_ok);
+		gen_set_gpr(tcg_ctx, rs3, dat);
+
+        tcg_gen_movi_tl(tcg_ctx, cpu_LLbit, 0);
+
+        tcg_temp_free(tcg_ctx, adr);
+        tcg_temp_free(tcg_ctx, dat);
+        tcg_temp_free(tcg_ctx, token);
+    }
+    else if (operation == operation_CLL)
+    {
+		tcg_gen_movi_i32(tcg_ctx, cpu_LLbit, 0);
+    }
+    else
+    	printf("ERROR gen_mutual_exclusion \n");
+}
+
+
+static void gen_multiply(DisasContext *ctx, int rs1, int rs2, int operation)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+	TCGv r1 = tcg_temp_new(tcg_ctx);		//temp
+	TCGv r2 = tcg_temp_new(tcg_ctx);		//temp
+
+	gen_get_gpr(tcg_ctx, r1, rs1);			//loading rs1 to t0
+	gen_get_gpr(tcg_ctx, r2, rs2);			//loading rs2 to t1
+	int imm = rs1;
+	int imm_32;
+	int int_rs3;
+
+	TCGv tcg_imm = tcg_temp_new(tcg_ctx);
+	TCGv tcg_imm32 = tcg_temp_new(tcg_ctx);
+	TCGv tcg_r3 = tcg_temp_new(tcg_ctx);
+	TCGv tcg_temp = tcg_temp_new(tcg_ctx);
+
+	switch(operation){
+		case OPC_RH850_MUL_reg1_reg2_reg3:
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, tcg_r3,int_rs3);
+
+			tcg_gen_muls2_i32(tcg_ctx, r2, tcg_r3, r1, r2);
+			if(rs2!=int_rs3){
+				gen_set_gpr(tcg_ctx, rs2, r2);
+			}
+			gen_set_gpr(tcg_ctx, int_rs3,tcg_r3);
+			break;
+
+		case OPC_RH850_MUL_imm9_reg2_reg3:
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, tcg_r3,int_rs3);
+
+			imm_32 = extract32(ctx->opcode, 18, 4);
+			imm_32 = imm | (imm_32 << 5);
+
+			// sign extension
+			if((imm_32 & 0x100) == 0x100){
+				imm_32 = imm_32 | (0x7f << 9);
+			}
+			tcg_gen_movi_tl(tcg_ctx, tcg_imm32, imm_32);
+			tcg_gen_ext16s_tl(tcg_ctx, tcg_imm32, tcg_imm32);
+
+			tcg_gen_muls2_i32(tcg_ctx, r2, tcg_r3, tcg_imm32, r2);
+
+			if(rs2!=int_rs3){
+				gen_set_gpr(tcg_ctx, rs2, r2);
+			}
+			gen_set_gpr(tcg_ctx, int_rs3, tcg_r3);
+			break;
+
+		case OPC_RH850_MULH_reg1_reg2:
+
+			tcg_gen_andi_tl(tcg_ctx, r1, r1,0x0000FFFF);
+			tcg_gen_andi_tl(tcg_ctx, r2, r2,0x0000FFFF);
+			tcg_gen_ext16s_i32(tcg_ctx, r1, r1);
+			tcg_gen_ext16s_i32(tcg_ctx, r2, r2);
+
+			tcg_gen_mul_tl(tcg_ctx, r2, r2, r1);
+			gen_set_gpr(tcg_ctx, rs2, r2);
+			break;
+
+		case OPC_RH850_MULH_imm5_reg2:
+
+			if ((imm & 0x10) == 0x10){
+				imm = imm | (0x7 << 5);
+			}
+			tcg_gen_andi_tl(tcg_ctx, r2, r2,0x0000FFFF);
+			tcg_gen_ext16s_i32(tcg_ctx, r2, r2);
+
+			tcg_gen_movi_tl(tcg_ctx, tcg_imm, imm);
+			tcg_gen_ext8s_i32(tcg_ctx, tcg_imm, tcg_imm);
+			tcg_gen_mul_tl(tcg_ctx, r2, r2, tcg_imm);
+			gen_set_gpr(tcg_ctx, rs2, r2);
+			break;
+
+		case OPC_RH850_MULHI_imm16_reg1_reg2:
+
+			imm_32 = extract32(ctx->opcode, 16, 16);
+			tcg_gen_movi_tl(tcg_ctx, tcg_imm32, imm_32);
+			tcg_gen_ext16s_i32(tcg_ctx, tcg_imm32, tcg_imm32);
+
+			tcg_gen_andi_tl(tcg_ctx, r1, r1, 0x0000FFFF);
+			tcg_gen_ext16s_i32(tcg_ctx, r1, r1);
+
+			tcg_gen_mul_tl(tcg_ctx, r2, r1, tcg_imm32);
+
+			gen_set_gpr(tcg_ctx, rs2, r2);
+			break;
+
+		case OPC_RH850_MULU_reg1_reg2_reg3:
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, tcg_r3,int_rs3);
+
+			tcg_gen_mulu2_i32(tcg_ctx, r2, tcg_r3, r2, r1);
+
+			if(rs2!=int_rs3){
+				gen_set_gpr(tcg_ctx, rs2, r2);
+			}
+			gen_set_gpr(tcg_ctx, int_rs3,tcg_r3);
+			break;
+
+		case OPC_RH850_MULU_imm9_reg2_reg3:
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, tcg_r3,int_rs3);
+
+			imm_32 = extract32(ctx->opcode, 18, 4);
+			imm_32 = imm | (imm_32 << 5);
+			tcg_gen_movi_tl(tcg_ctx, tcg_imm32, imm_32);
+
+			tcg_gen_ext16u_tl(tcg_ctx, tcg_imm32, tcg_imm32);
+
+			tcg_gen_mulu2_i32(tcg_ctx, r2, tcg_r3, tcg_imm32, r2);
+
+			if(rs2!=int_rs3){
+				gen_set_gpr(tcg_ctx, rs2, r2);
+			}
+			gen_set_gpr(tcg_ctx, int_rs3,tcg_r3);
+			break;
+	}
+
+	tcg_temp_free(tcg_ctx, r1);
+	tcg_temp_free(tcg_ctx, r2);
+	tcg_temp_free(tcg_ctx, tcg_r3);
+	tcg_temp_free(tcg_ctx, tcg_temp);
+	tcg_temp_free(tcg_ctx, tcg_imm);
+	tcg_temp_free(tcg_ctx, tcg_imm32);
+}
+
+static void gen_mul_accumulate(DisasContext *ctx, int rs1, int rs2, int operation)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+	TCGv r1 = tcg_temp_new(tcg_ctx);
+	TCGv r2 = tcg_temp_new(tcg_ctx);
+	TCGv addLo = tcg_temp_new(tcg_ctx);
+	TCGv addHi = tcg_temp_new(tcg_ctx);
+	TCGv resLo = tcg_temp_new(tcg_ctx);
+	TCGv resHi = tcg_temp_new(tcg_ctx);
+	TCGv destLo = tcg_temp_new(tcg_ctx);
+	TCGv destHi = tcg_temp_new(tcg_ctx);
+
+	gen_get_gpr(tcg_ctx, r1, rs1);
+	gen_get_gpr(tcg_ctx, r2, rs2);
+
+	int rs3;
+	int rs4;
+
+	rs3 = extract32(ctx->opcode, 28, 4) << 1;
+	rs4 = extract32(ctx->opcode, 17, 4) << 1;
+
+	gen_get_gpr(tcg_ctx, addLo, rs3);
+	gen_get_gpr(tcg_ctx, addHi, rs3+1);
+
+	switch(operation){
+		case OPC_RH850_MAC_reg1_reg2_reg3_reg4:
+
+			tcg_gen_muls2_i32(tcg_ctx, resLo, resHi, r1, r2);
+			tcg_gen_add2_i32(tcg_ctx, destLo, destHi, resLo, resHi, addLo, addHi);
+
+			gen_set_gpr(tcg_ctx, rs4, destLo);
+			gen_set_gpr(tcg_ctx, rs4+1, destHi);
+			break;
+
+		case OPC_RH850_MACU_reg1_reg2_reg3_reg4:
+			tcg_gen_mulu2_i32(tcg_ctx, resLo, resHi, r1, r2);
+			tcg_gen_add2_i32(tcg_ctx, destLo, destHi, resLo, resHi, addLo, addHi);
+
+			gen_set_gpr(tcg_ctx, rs4, destLo);
+			gen_set_gpr(tcg_ctx, (rs4+1), destHi);
+			break;
+	}
+
+    tcg_temp_free(tcg_ctx, r1);
+    tcg_temp_free(tcg_ctx, r2);
+    tcg_temp_free(tcg_ctx, addLo);
+    tcg_temp_free(tcg_ctx, addHi);
+    tcg_temp_free(tcg_ctx, resLo);
+    tcg_temp_free(tcg_ctx, resHi);
+    tcg_temp_free(tcg_ctx, destLo);
+    tcg_temp_free(tcg_ctx, destHi);
+
+}
+
+static void gen_arithmetic(DisasContext *ctx, int rs1, int rs2, int operation)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+	TCGv r1 = tcg_temp_new(tcg_ctx);
+	TCGv r2 = tcg_temp_new(tcg_ctx);
+	gen_get_gpr(tcg_ctx, r1, rs1);
+	gen_get_gpr(tcg_ctx, r2, rs2);
+
+	int imm = rs1;
+	int imm_32;
+	uint64_t opcode48;
+
+	TCGv tcg_imm = tcg_temp_new(tcg_ctx);
+	TCGv tcg_r3 = tcg_temp_new(tcg_ctx);
+	TCGv tcg_result = tcg_temp_new(tcg_ctx);
+
+	switch(operation) {
+
+		case OPC_RH850_ADD_reg1_reg2: {
+
+			tcg_gen_add_tl(tcg_ctx, tcg_result, r2, r1);
+			gen_set_gpr(tcg_ctx, rs2, tcg_result);
+
+			gen_flags_on_add(tcg_ctx, r1, r2);
+
+		}	break;
+
+		case OPC_RH850_ADD_imm5_reg2:
+			if((imm & 0x10) == 0x10){
+				imm = imm | (0x7 << 5);
+			}
+			tcg_gen_movi_i32(tcg_ctx, tcg_imm, imm);
+			tcg_gen_ext8s_i32(tcg_ctx, tcg_imm, tcg_imm);
+			tcg_gen_add_tl(tcg_ctx, tcg_result, r2, tcg_imm);
+			gen_set_gpr(tcg_ctx, rs2, tcg_result);
+
+			gen_flags_on_add(tcg_ctx, r2, tcg_imm);
+
+			break;
+
+		case OPC_RH850_ADDI_imm16_reg1_reg2:
+			imm_32 = extract32(ctx->opcode, 16, 16);
+			tcg_gen_movi_tl(tcg_ctx, tcg_imm, imm_32);
+			tcg_gen_ext16s_tl(tcg_ctx, tcg_imm, tcg_imm);
+			tcg_gen_add_tl(tcg_ctx, r2,r1, tcg_imm);
+			gen_set_gpr(tcg_ctx, rs2, r2);
+
+			gen_flags_on_add(tcg_ctx, r1, tcg_imm);
+
+			break;
+
+		case OPC_RH850_CMP_reg1_reg2:	{
+			gen_flags_on_sub(tcg_ctx, r2, r1);
+		}	break;
+
+		case OPC_RH850_CMP_imm5_reg2:	{
+
+			if ((imm & 0x10) == 0x10){
+				imm = imm | (0x7 << 5);
+			}
+			tcg_gen_movi_tl(tcg_ctx, tcg_imm, imm);
+			tcg_gen_ext8s_i32(tcg_ctx, tcg_imm, tcg_imm);
+
+			gen_flags_on_sub(tcg_ctx, r2, tcg_imm);
+
+		}	break;
+
+		case OPC_RH850_MOV_reg1_reg2:
+			tcg_gen_mov_tl(tcg_ctx, r2, r1);
+			gen_set_gpr(tcg_ctx, rs2, r2);
+			break;
+
+		case OPC_RH850_MOV_imm5_reg2:
+			if ((imm & 0x10) == 0x10){
+				imm = imm | (0x7 << 5);
+			}
+			tcg_gen_movi_tl(tcg_ctx, r2, imm);
+			tcg_gen_ext8s_i32(tcg_ctx, r2, r2);
+
+			gen_set_gpr(tcg_ctx, rs2, r2);
+			break;
+
+		case OPC_RH850_MOV_imm32_reg1:	// 48bit instruction
+			opcode48 = (ctx->opcode1);
+			opcode48 = (ctx->opcode) | (opcode48  << 0x20);
+			imm_32 = extract64(opcode48, 16, 32) & 0xffffffff;
+			tcg_gen_movi_i32(tcg_ctx, r2, imm_32);
+			gen_set_gpr(tcg_ctx, rs2, r2);
+			break;
+
+		case OPC_RH850_MOVEA_imm16_reg1_reg2:
+			imm_32 = extract32(ctx->opcode, 16, 16);
+			tcg_gen_movi_i32(tcg_ctx, tcg_imm, imm_32);
+			tcg_gen_ext16s_i32(tcg_ctx, tcg_imm, tcg_imm);
+
+			tcg_gen_add_i32(tcg_ctx, r2, tcg_imm, r1);
+			gen_set_gpr(tcg_ctx, rs2, r2);
+			break;
+
+		case OPC_RH850_MOVHI_imm16_reg1_reg2:
+			imm_32 = extract32(ctx->opcode, 16, 16);
+			tcg_gen_movi_i32(tcg_ctx, tcg_imm, imm_32);
+			tcg_gen_shli_i32(tcg_ctx, tcg_imm, tcg_imm, 0x10);
+
+			tcg_gen_add_i32(tcg_ctx, r2, tcg_imm, r1);
+			gen_set_gpr(tcg_ctx, rs2, r2);
+			break;
+
+		case OPC_RH850_SUB_reg1_reg2:
+
+			tcg_gen_sub_tl(tcg_ctx, tcg_result, r2, r1);
+			gen_set_gpr(tcg_ctx, rs2, tcg_result);
+			gen_flags_on_sub(tcg_ctx, r2, r1);
+			break;
+
+		case OPC_RH850_SUBR_reg1_reg2:
+			tcg_gen_sub_tl(tcg_ctx, tcg_result, r1, r2);
+			gen_set_gpr(tcg_ctx, rs2, tcg_result);
+			gen_flags_on_sub(tcg_ctx, r1, r2);
+			break;
+	}
+
+	tcg_temp_free(tcg_ctx, r1);
+	tcg_temp_free(tcg_ctx, r2);
+    tcg_temp_free(tcg_ctx, tcg_imm);
+	tcg_temp_free(tcg_ctx, tcg_r3);
+	tcg_temp_free(tcg_ctx, tcg_result);
+}
+
+static void gen_cond_arith(DisasContext *ctx, int rs1, int rs2, int operation)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+	TCGv r1 = tcg_temp_local_new(tcg_ctx);
+	TCGv r2 = tcg_temp_local_new(tcg_ctx);
+
+	TCGLabel *cont;
+
+	gen_get_gpr(tcg_ctx, r1, rs1);
+	gen_get_gpr(tcg_ctx, r2, rs2);
+
+	int int_rs3;
+	int int_cond;
+
+    switch(operation){
+
+		case OPC_RH850_ADF_cccc_reg1_reg2_reg3:{
+
+			TCGv r1_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv addIfCond = tcg_temp_local_new_i32(tcg_ctx);
+            TCGv carry = tcg_temp_local_new_i32(tcg_ctx);
+            TCGv overflow = tcg_temp_local_new_i32(tcg_ctx);
+
+            tcg_gen_movi_tl(tcg_ctx, carry, 0);
+            tcg_gen_movi_tl(tcg_ctx, overflow, 0);
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			int_cond = extract32(ctx->opcode, 17, 4);
+			if(int_cond == 0xd){
+				//throw exception/warning for inappropriate condition (SA)
+				break;
+			}
+
+			tcg_gen_mov_i32(tcg_ctx, r1_local, r1);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, r2);
+			gen_get_gpr(tcg_ctx, r3_local,int_rs3);
+			tcg_gen_movi_i32(tcg_ctx, addIfCond, 0x1);
+
+			TCGv condResult = condition_satisfied(tcg_ctx, int_cond);
+			cont = gen_new_label(tcg_ctx);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, condResult, 0x1, cont);
+			  // calc and store CY and OV flags to be used to obtain final values
+              gen_flags_on_add(tcg_ctx, r2_local, addIfCond);
+              tcg_gen_mov_tl(tcg_ctx, carry, cpu_CYF);
+              tcg_gen_mov_tl(tcg_ctx, overflow, cpu_OVF);
+              // on cond true, add 1
+              tcg_gen_add_tl(tcg_ctx, r2_local, r2_local, addIfCond);
+
+			gen_set_label(tcg_ctx, cont);
+            tcg_gen_add_tl(tcg_ctx, r3_local, r1_local, r2_local);
+			gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+
+			gen_flags_on_add(tcg_ctx, r1_local, r2_local);
+			tcg_gen_or_tl(tcg_ctx, cpu_CYF, cpu_CYF, carry);
+            tcg_gen_or_tl(tcg_ctx, cpu_OVF, cpu_OVF, overflow);
+
+		    tcg_temp_free(tcg_ctx, condResult);
+			tcg_temp_free_i32(tcg_ctx, r1_local);
+			tcg_temp_free_i32(tcg_ctx, r2_local);
+			tcg_temp_free_i32(tcg_ctx, r3_local);
+            tcg_temp_free_i32(tcg_ctx, addIfCond);
+		}
+			break;
+
+		case OPC_RH850_SBF_cccc_reg1_reg2_reg3:{
+
+		    int_rs3 = extract32(ctx->opcode, 27, 5);
+            int_cond = extract32(ctx->opcode, 17, 4);
+            if(int_cond == 0xd){
+                //throw exception/warning for inappropriate condition (SA)
+                break;
+            }
+
+			TCGv r3_local = tcg_temp_local_new(tcg_ctx);
+			TCGv tmpReg = tcg_temp_local_new(tcg_ctx);
+            TCGv carry = tcg_temp_local_new(tcg_ctx);
+            TCGv overflow = tcg_temp_local_new(tcg_ctx);
+            cont = gen_new_label(tcg_ctx);
+
+            tcg_gen_movi_tl(tcg_ctx, carry, 0);
+            tcg_gen_movi_tl(tcg_ctx, overflow, 0);
+
+			tcg_gen_mov_i32(tcg_ctx, r3_local, r2);
+
+            TCGv condResult = condition_satisfied(tcg_ctx, int_cond);
+            // store to local temp, because condResult is valid only until branch in gen_flags_on_sub
+            tcg_gen_mov_tl(tcg_ctx, tmpReg, condResult);
+
+            gen_flags_on_sub(tcg_ctx, r3_local, r1);
+            tcg_gen_mov_tl(tcg_ctx, carry, cpu_CYF);
+            tcg_gen_mov_tl(tcg_ctx, overflow, cpu_OVF);
+            tcg_gen_sub_tl(tcg_ctx, r3_local, r3_local, r1);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, tmpReg, 0x1, cont);
+              tcg_gen_movi_i32(tcg_ctx, tmpReg, 0x1);
+              gen_flags_on_sub(tcg_ctx, r3_local, tmpReg);
+              tcg_gen_subi_tl(tcg_ctx, r3_local, r3_local, 1);
+              tcg_gen_or_tl(tcg_ctx, cpu_CYF, cpu_CYF, carry);
+              // overflow twice means no overflow
+              tcg_gen_xor_tl(tcg_ctx, cpu_OVF, cpu_OVF, overflow);
+
+            gen_set_label(tcg_ctx, cont);
+
+			gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+
+            tcg_temp_free(tcg_ctx, condResult);
+			tcg_temp_free_i32(tcg_ctx, r3_local);
+            tcg_temp_free_i32(tcg_ctx, tmpReg);
+            tcg_temp_free_i32(tcg_ctx, overflow);
+            tcg_temp_free_i32(tcg_ctx, carry);
+		}
+			break;
+	}
+
+	tcg_temp_free_i32(tcg_ctx, r1);
+	tcg_temp_free_i32(tcg_ctx, r2);
+}
+
+static void gen_sat_op(DisasContext *ctx, int rs1, int rs2, int operation)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+	TCGv r1 = tcg_temp_new(tcg_ctx);
+	TCGv r2 = tcg_temp_new(tcg_ctx);
+	gen_get_gpr(tcg_ctx, r1, rs1);
+	gen_get_gpr(tcg_ctx, r2, rs2);
+
+	int imm = rs1;
+	int int_rs3;
+
+	TCGLabel *end;
+	TCGLabel *cont;
+	TCGLabel *cont2;
+	TCGLabel *setMax;
+	TCGLabel *dontChange;
+
+	switch(operation){
+
+		case OPC_RH850_SATADD_reg1_reg2: {
+
+			TCGv r1_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv result = tcg_temp_local_new(tcg_ctx);
+			TCGv check = tcg_temp_local_new(tcg_ctx);
+			TCGv min = tcg_temp_local_new(tcg_ctx);
+			TCGv max = tcg_temp_local_new(tcg_ctx);
+			TCGv zero = tcg_temp_local_new(tcg_ctx);
+			tcg_gen_movi_i32(tcg_ctx, min, 0x80000000);
+			tcg_gen_movi_i32(tcg_ctx, max, 0x7fffffff);
+			tcg_gen_mov_i32(tcg_ctx, r1_local, r1);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, r2);
+			tcg_gen_movi_i32(tcg_ctx, zero, 0x0);
+			end = gen_new_label(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+			cont2 = gen_new_label(tcg_ctx);
+
+
+			tcg_gen_add_i32(tcg_ctx, result, r1_local, r2_local);
+
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LT, r1_local, zero, cont);
+
+			tcg_gen_sub_i32(tcg_ctx, check, max, r1_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LE, r2_local, check, end);
+			tcg_gen_mov_i32(tcg_ctx, result, max);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+			tcg_gen_br(tcg_ctx, end);
+
+			//---------------------------------------------------------------------------------
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_sub_i32(tcg_ctx, check, min, r1_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_GE, r2_local, check, cont2);
+			tcg_gen_mov_i32(tcg_ctx, result, min);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+
+			gen_set_label(tcg_ctx, cont2);
+			gen_set_label(tcg_ctx, end);
+			gen_set_gpr(tcg_ctx, rs2, result);
+
+			gen_satadd_CC(tcg_ctx, r1_local, r2_local, result);  // moves also SET flag to psw
+
+			tcg_temp_free(tcg_ctx, result);
+			tcg_temp_free(tcg_ctx, check);
+			tcg_temp_free(tcg_ctx, min);
+			tcg_temp_free(tcg_ctx, max);
+			tcg_temp_free(tcg_ctx, r1_local);
+			tcg_temp_free(tcg_ctx, r2_local);
+			tcg_temp_free(tcg_ctx, zero);
+
+		}	break;
+
+		case OPC_RH850_SATADD_imm5_reg2: {
+
+			TCGv imm_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv result = tcg_temp_local_new(tcg_ctx);
+			TCGv check = tcg_temp_local_new(tcg_ctx);
+			TCGv min = tcg_temp_local_new(tcg_ctx);
+			TCGv max = tcg_temp_local_new(tcg_ctx);
+			TCGv zero = tcg_temp_local_new(tcg_ctx);
+			tcg_gen_movi_i32(tcg_ctx, min, 0x80000000);
+			tcg_gen_movi_i32(tcg_ctx, max, 0x7fffffff);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, r2);
+			tcg_gen_movi_i32(tcg_ctx, zero, 0x0);
+			end = gen_new_label(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+			cont2 = gen_new_label(tcg_ctx);
+
+			if ((imm & 0x10) == 0x10){
+				imm = imm | (0x7 << 5);
+			}
+
+			tcg_gen_movi_tl(tcg_ctx, imm_local, imm);
+			tcg_gen_ext8s_tl(tcg_ctx, imm_local, imm_local);
+
+			tcg_gen_add_i32(tcg_ctx, result, imm_local, r2_local);
+
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LT, imm_local, zero, cont);
+
+			tcg_gen_sub_i32(tcg_ctx, check, max, imm_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LE, r2_local, check, end);
+			tcg_gen_mov_i32(tcg_ctx, result, max);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+			tcg_gen_br(tcg_ctx, end);
+
+			//---------------------------------------------------------------------------------
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_sub_i32(tcg_ctx, check, min, imm_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_GE, r2_local, check, cont2);
+			tcg_gen_mov_i32(tcg_ctx, result, min);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+
+			gen_set_label(tcg_ctx, cont2);
+			gen_set_label(tcg_ctx, end);
+			gen_set_gpr(tcg_ctx, rs2, result);
+
+			gen_satadd_CC(tcg_ctx, r2_local, imm_local, result);
+
+			tcg_temp_free(tcg_ctx, result);
+			tcg_temp_free(tcg_ctx, check);
+			tcg_temp_free(tcg_ctx, min);
+			tcg_temp_free(tcg_ctx, max);
+			tcg_temp_free(tcg_ctx, imm_local);
+			tcg_temp_free(tcg_ctx, r2_local);
+			tcg_temp_free(tcg_ctx, zero);
+
+		}	break;
+
+		case OPC_RH850_SATADD_reg1_reg2_reg3: {
+
+			TCGv r1_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv result = tcg_temp_local_new(tcg_ctx);
+			TCGv check = tcg_temp_local_new(tcg_ctx);
+			TCGv min = tcg_temp_local_new(tcg_ctx);
+			TCGv max = tcg_temp_local_new(tcg_ctx);
+			TCGv zero = tcg_temp_local_new(tcg_ctx);
+			tcg_gen_movi_i32(tcg_ctx, min, 0x80000000);
+			tcg_gen_movi_i32(tcg_ctx, max, 0x7fffffff);
+			tcg_gen_mov_i32(tcg_ctx, r1_local, r1);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, r2);
+			tcg_gen_movi_i32(tcg_ctx, zero, 0x0);
+			end = gen_new_label(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+			cont2 = gen_new_label(tcg_ctx);
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			tcg_gen_add_i32(tcg_ctx, result, r1_local, r2_local);
+
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LT, r1_local, zero, cont);		//if (r1 > 0)
+
+			tcg_gen_sub_i32(tcg_ctx, check, max, r1_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LE, r2_local, check, end);			//if (r2 > MAX-r1)
+			tcg_gen_mov_i32(tcg_ctx, result, max);										//return MAX;
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+			tcg_gen_br(tcg_ctx, end);
+
+			//---------------------------------------------------------------------------------
+			gen_set_label(tcg_ctx, cont); 										//else
+			tcg_gen_sub_i32(tcg_ctx, check, min, r1_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_GE, r2_local, check, cont2);		//if (r2 < MIN-r1)
+			tcg_gen_mov_i32(tcg_ctx, result, min);										//return MIN;
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+
+			gen_set_label(tcg_ctx, cont2);
+			gen_set_label(tcg_ctx, end);
+			gen_set_gpr(tcg_ctx, int_rs3, result);
+
+			gen_satadd_CC(tcg_ctx, r1_local, r2_local, result);
+
+			tcg_temp_free(tcg_ctx, result);
+			tcg_temp_free(tcg_ctx, check);
+			tcg_temp_free(tcg_ctx, min);
+			tcg_temp_free(tcg_ctx, max);
+			tcg_temp_free(tcg_ctx, r1_local);
+			tcg_temp_free(tcg_ctx, r2_local);
+			tcg_temp_free(tcg_ctx, zero);
+
+		}	break;
+
+		case OPC_RH850_SATSUB_reg1_reg2: {
+
+			TCGv r1_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv result = tcg_temp_local_new(tcg_ctx);
+			TCGv check = tcg_temp_local_new(tcg_ctx);
+			TCGv min = tcg_temp_local_new(tcg_ctx);
+			TCGv max = tcg_temp_local_new(tcg_ctx);
+			TCGv zero = tcg_temp_local_new(tcg_ctx);
+			tcg_gen_movi_i32(tcg_ctx, min, 0x80000000);
+			tcg_gen_movi_i32(tcg_ctx, max, 0x7fffffff);
+			tcg_gen_mov_i32(tcg_ctx, r1_local, r1);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, r2);
+			tcg_gen_movi_i32(tcg_ctx, zero, 0x0);
+			end = gen_new_label(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+			cont2 = gen_new_label(tcg_ctx);
+			setMax = gen_new_label(tcg_ctx);
+			dontChange = gen_new_label(tcg_ctx);
+
+			/*
+			 * Negating second operand and using satadd code. When negating an operand
+			 * with value 0x80000000, the result overflows positive numbers and is not
+			 * negated. If this happens, the operand is first incremented, and then negated.
+			 * The second operand is as well incremented, if it's value is less than 0x7fffffff.
+			 * Otherwise, the result is set to MAX and SATF is set.
+			 * This was done in all following saturated subtraction functions.
+			 */
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, r1_local, 0x80000000, dontChange);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, r2_local, 0x7fffffff, setMax);
+
+			tcg_gen_addi_i32(tcg_ctx, r1_local, r1_local, 0x1);
+			tcg_gen_addi_i32(tcg_ctx, r2_local, r2_local, 0x1);
+			gen_set_label(tcg_ctx, dontChange);
+
+			tcg_gen_neg_i32(tcg_ctx, r1_local, r1_local);
+			tcg_gen_add_i32(tcg_ctx, result, r1_local, r2_local);
+
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LT, r1_local, zero, cont);
+
+			tcg_gen_sub_i32(tcg_ctx, check, max, r1_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LE, r2_local, check, end);
+			gen_set_label(tcg_ctx, setMax);
+			tcg_gen_mov_i32(tcg_ctx, result, max);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+			tcg_gen_br(tcg_ctx, end);
+
+			//---------------------------------------------------------------------------------
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_sub_i32(tcg_ctx, check, min, r1_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_GE, r2_local, check, cont2);
+			tcg_gen_mov_i32(tcg_ctx, result, min);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+
+			gen_set_label(tcg_ctx, cont2);
+			gen_set_label(tcg_ctx, end);
+			gen_set_gpr(tcg_ctx, rs2, result);
+
+			// second negation is needed for appropriate flag calculation
+			tcg_gen_neg_i32(tcg_ctx, r1_local, r1_local);
+			gen_satsub_CC(tcg_ctx, r2_local, r1_local, result);
+
+			tcg_temp_free(tcg_ctx, result);
+			tcg_temp_free(tcg_ctx, check);
+			tcg_temp_free(tcg_ctx, min);
+			tcg_temp_free(tcg_ctx, max);
+			tcg_temp_free(tcg_ctx, r1_local);
+			tcg_temp_free(tcg_ctx, r2_local);
+			tcg_temp_free(tcg_ctx, zero);
+
+		}	break;
+
+		case OPC_RH850_SATSUB_reg1_reg2_reg3: {
+			TCGv r1_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv result = tcg_temp_local_new(tcg_ctx);
+			TCGv check = tcg_temp_local_new(tcg_ctx);
+			TCGv min = tcg_temp_local_new(tcg_ctx);
+			TCGv max = tcg_temp_local_new(tcg_ctx);
+			TCGv zero = tcg_temp_local_new(tcg_ctx);
+			tcg_gen_movi_i32(tcg_ctx, min, 0x80000000);
+			tcg_gen_movi_i32(tcg_ctx, max, 0x7fffffff);
+			tcg_gen_mov_i32(tcg_ctx, r1_local, r1);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, r2);
+			tcg_gen_movi_i32(tcg_ctx, zero, 0x0);
+			end = gen_new_label(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+			cont2 = gen_new_label(tcg_ctx);
+			setMax = gen_new_label(tcg_ctx);
+			dontChange = gen_new_label(tcg_ctx);
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, r1_local, 0x80000000, dontChange);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, r2_local, 0x7fffffff, setMax);
+
+			tcg_gen_addi_i32(tcg_ctx, r1_local, r1_local, 0x1);
+			tcg_gen_addi_i32(tcg_ctx, r2_local, r2_local, 0x1);
+			gen_set_label(tcg_ctx, dontChange);
+
+			tcg_gen_neg_i32(tcg_ctx, r1_local, r1_local);
+			tcg_gen_add_i32(tcg_ctx, result, r1_local, r2_local);
+
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LT, r1_local, zero, cont);
+
+			tcg_gen_sub_i32(tcg_ctx, check, max, r1_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LE, r2_local, check, end);
+			gen_set_label(tcg_ctx, setMax);
+			tcg_gen_mov_i32(tcg_ctx, result, max);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+			tcg_gen_br(tcg_ctx, end);
+
+			//---------------------------------------------------------------------------------
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_sub_i32(tcg_ctx, check, min, r1_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_GE, r2_local, check, cont2);
+			tcg_gen_mov_i32(tcg_ctx, result, min);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+
+			gen_set_label(tcg_ctx, cont2);
+			gen_set_label(tcg_ctx, end);
+			gen_set_gpr(tcg_ctx, int_rs3, result);
+
+			tcg_gen_neg_i32(tcg_ctx, r1_local, r1_local);
+			gen_satsub_CC(tcg_ctx, r2_local, r1_local, result);
+
+			tcg_temp_free(tcg_ctx, result);
+			tcg_temp_free(tcg_ctx, check);
+			tcg_temp_free(tcg_ctx, min);
+			tcg_temp_free(tcg_ctx, max);
+			tcg_temp_free(tcg_ctx, r1_local);
+			tcg_temp_free(tcg_ctx, r2_local);
+			tcg_temp_free(tcg_ctx, zero); 
+
+		}	break;
+
+		case OPC_RH850_SATSUBI_imm16_reg1_reg2: {
+			TCGv r1_local = tcg_temp_local_new(tcg_ctx);
+			TCGv imm_local = tcg_temp_local_new(tcg_ctx);
+			TCGv result = tcg_temp_local_new(tcg_ctx);
+			TCGv check = tcg_temp_local_new(tcg_ctx);
+			TCGv min = tcg_temp_local_new(tcg_ctx);
+			TCGv max = tcg_temp_local_new(tcg_ctx);
+			TCGv zero = tcg_temp_local_new(tcg_ctx);
+			tcg_gen_movi_i32(tcg_ctx, min, 0x80000000);
+			tcg_gen_movi_i32(tcg_ctx, max, 0x7fffffff);
+			tcg_gen_mov_i32(tcg_ctx, r1_local, r1);
+			imm = extract32(ctx->opcode, 16, 16);
+			tcg_gen_movi_i32(tcg_ctx, imm_local, imm);
+			tcg_gen_ext16s_i32(tcg_ctx, imm_local, imm_local);
+			tcg_gen_movi_i32(tcg_ctx, zero, 0x0);
+			end = gen_new_label(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+			cont2 = gen_new_label(tcg_ctx);
+			setMax = gen_new_label(tcg_ctx);
+			dontChange = gen_new_label(tcg_ctx);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, r1_local, 0x80000000, dontChange);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, imm_local, 0x7fffffff, setMax);
+
+			tcg_gen_addi_i32(tcg_ctx, r1_local, r1_local, 0x1);
+			tcg_gen_addi_i32(tcg_ctx, imm_local, imm_local, 0x1);
+			gen_set_label(tcg_ctx, dontChange);
+
+
+			tcg_gen_neg_i32(tcg_ctx, imm_local, imm_local);
+
+			tcg_gen_add_i32(tcg_ctx, result, r1_local, imm_local);
+
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LT, r1_local, zero, cont);
+
+			tcg_gen_sub_i32(tcg_ctx, check, max, r1_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LE, imm_local, check, end);
+			gen_set_label(tcg_ctx, setMax);
+			tcg_gen_mov_i32(tcg_ctx, result, max);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+			tcg_gen_br(tcg_ctx, end);
+
+			//---------------------------------------------------------------------------------
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_sub_i32(tcg_ctx, check, min, r1_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_GE, imm_local, check, cont2);
+			tcg_gen_mov_i32(tcg_ctx, result, min);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+
+			gen_set_label(tcg_ctx, cont2);
+			gen_set_label(tcg_ctx, end);
+			gen_set_gpr(tcg_ctx, rs2, result);
+
+			tcg_gen_neg_i32(tcg_ctx, imm_local, imm_local);
+			gen_satsub_CC(tcg_ctx, r1_local, imm_local, result);
+
+			tcg_temp_free(tcg_ctx, result);
+			tcg_temp_free(tcg_ctx, check);
+			tcg_temp_free(tcg_ctx, min);
+			tcg_temp_free(tcg_ctx, max);
+			tcg_temp_free(tcg_ctx, r1_local);
+			tcg_temp_free(tcg_ctx, imm_local);
+			tcg_temp_free(tcg_ctx, zero);
+
+		}	break;
+
+		case OPC_RH850_SATSUBR_reg1_reg2: {
+
+			TCGv r1_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv result = tcg_temp_local_new(tcg_ctx);
+			TCGv check = tcg_temp_local_new(tcg_ctx);
+			TCGv min = tcg_temp_local_new(tcg_ctx);
+			TCGv max = tcg_temp_local_new(tcg_ctx);
+			TCGv zero = tcg_temp_local_new(tcg_ctx);
+			tcg_gen_movi_i32(tcg_ctx, min, 0x80000000);
+			tcg_gen_movi_i32(tcg_ctx, max, 0x7fffffff);
+			tcg_gen_mov_i32(tcg_ctx, r1_local, r2);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, r1);
+			tcg_gen_movi_i32(tcg_ctx, zero, 0x0);
+			end = gen_new_label(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+			cont2 = gen_new_label(tcg_ctx);
+			setMax = gen_new_label(tcg_ctx);
+			dontChange = gen_new_label(tcg_ctx);
+
+			/*
+			 * Negating second operand and using satadd code. When negating an operand
+			 * with value 0x80000000, the result overflows positive numbers and is not
+			 * negated. If this happens, the operand is first incremented, and then negated.
+			 * The second operand is as well incremented, if it's value is less than 0x7fffffff.
+			 * Otherwise, the result is set to MAX and SATF is set.
+			 * This was done in all following saturated subtraction functions.
+			 */
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, r1_local, 0x80000000, dontChange);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, r2_local, 0x7fffffff, setMax);
+
+			tcg_gen_addi_i32(tcg_ctx, r1_local, r1_local, 0x1);
+			tcg_gen_addi_i32(tcg_ctx, r2_local, r2_local, 0x1);
+			gen_set_label(tcg_ctx, dontChange);
+
+			tcg_gen_neg_i32(tcg_ctx, r1_local, r1_local);
+			tcg_gen_add_i32(tcg_ctx, result, r1_local, r2_local);
+
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LT, r1_local, zero, cont);
+
+			tcg_gen_sub_i32(tcg_ctx, check, max, r1_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_LE, r2_local, check, end);
+			gen_set_label(tcg_ctx, setMax);
+			tcg_gen_mov_i32(tcg_ctx, result, max);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+			tcg_gen_br(tcg_ctx, end);
+
+			//---------------------------------------------------------------------------------
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_sub_i32(tcg_ctx, check, min, r1_local);
+			tcg_gen_brcond_tl(tcg_ctx, TCG_COND_GE, r2_local, check, cont2);
+			tcg_gen_mov_i32(tcg_ctx, result, min);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SATF, 0x1);
+
+			gen_set_label(tcg_ctx, cont2);
+			gen_set_label(tcg_ctx, end);
+			gen_set_gpr(tcg_ctx, rs2, result);
+
+			tcg_gen_neg_i32(tcg_ctx, r1_local, r1_local);
+			gen_satsub_CC(tcg_ctx, r2_local, r1_local, result);
+
+			tcg_temp_free(tcg_ctx, result);
+			tcg_temp_free(tcg_ctx, check);
+			tcg_temp_free(tcg_ctx, min);
+			tcg_temp_free(tcg_ctx, max);
+			tcg_temp_free(tcg_ctx, r1_local);
+			tcg_temp_free(tcg_ctx, r2_local);
+			tcg_temp_free(tcg_ctx, zero);
+
+		}	break;
+	}
+
+	tcg_temp_free(tcg_ctx, r1);
+	tcg_temp_free(tcg_ctx, r2);
+}
+
+static void gen_logical(DisasContext *ctx, int rs1, int rs2, int operation)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+	TCGv r1 = tcg_temp_new(tcg_ctx);
+	TCGv r2 = tcg_temp_new(tcg_ctx);
+	TCGv result = tcg_temp_new(tcg_ctx);
+	gen_get_gpr(tcg_ctx, r1, rs1);
+	gen_get_gpr(tcg_ctx, r2, rs2);
+
+	int imm_32;
+	TCGv tcg_imm = tcg_temp_new(tcg_ctx);
+
+	switch(operation){
+
+		case OPC_RH850_AND_reg1_reg2:
+			tcg_gen_and_tl(tcg_ctx, r2, r2, r1);
+			gen_set_gpr(tcg_ctx, rs2, r2);
+			gen_logic_CC(tcg_ctx, r2);
+			break;
+
+		case OPC_RH850_ANDI_imm16_reg1_reg2:
+			imm_32 = extract32(ctx->opcode, 16, 16);
+			tcg_gen_movi_tl(tcg_ctx, tcg_imm, imm_32);
+			tcg_gen_ext16u_i32(tcg_ctx, tcg_imm, tcg_imm);
+			tcg_gen_and_i32(tcg_ctx, r2, r1, tcg_imm);
+			gen_set_gpr(tcg_ctx, rs2, r2);
+			gen_logic_CC(tcg_ctx, r2);
+			break;
+
+		case OPC_RH850_NOT_reg1_reg2:
+			tcg_gen_not_i32(tcg_ctx, r2, r1);
+			gen_set_gpr(tcg_ctx, rs2, r2);
+			gen_logic_CC(tcg_ctx, r2);
+			break;
+
+		case OPC_RH850_OR_reg1_reg2:
+			tcg_gen_or_tl(tcg_ctx, r2, r2, r1);
+			gen_set_gpr(tcg_ctx, rs2, r2);
+			gen_logic_CC(tcg_ctx, r2);
+			break;
+
+		case OPC_RH850_ORI_imm16_reg1_reg2:
+			imm_32 = extract32(ctx->opcode, 16, 16);
+			tcg_gen_movi_i32(tcg_ctx, tcg_imm, imm_32);
+			tcg_gen_ext16u_i32(tcg_ctx, tcg_imm,tcg_imm);
+
+			tcg_gen_or_i32(tcg_ctx, r2, r1, tcg_imm);
+			gen_set_gpr(tcg_ctx, rs2, r2);
+			gen_logic_CC(tcg_ctx, r2);
+			break;
+
+		case OPC_RH850_TST_reg1_reg2:
+			tcg_gen_and_i32(tcg_ctx, result, r1, r2);
+			gen_logic_CC(tcg_ctx, result);
+			break;
+
+		case OPC_RH850_XOR_reg1_reg2:
+			tcg_gen_xor_i32(tcg_ctx, result, r2, r1);
+			gen_set_gpr(tcg_ctx, rs2, result);
+			gen_logic_CC(tcg_ctx, result);
+			break;
+
+		case OPC_RH850_XORI_imm16_reg1_reg2:
+			imm_32 = extract32(ctx->opcode, 16, 16);
+			tcg_gen_movi_i32(tcg_ctx, tcg_imm, imm_32);
+			tcg_gen_ext16u_i32(tcg_ctx, tcg_imm,tcg_imm);
+
+			tcg_gen_xor_i32(tcg_ctx, result, r1, tcg_imm);
+			gen_set_gpr(tcg_ctx, rs2, result);
+			gen_logic_CC(tcg_ctx, result);
+			break;
+	}
+
+	tcg_temp_free(tcg_ctx, r1);
+	tcg_temp_free(tcg_ctx, r2);
+	tcg_temp_free(tcg_ctx, tcg_imm);
+	tcg_temp_free(tcg_ctx, result);
+}
+
+static void gen_data_manipulation(DisasContext *ctx, int rs1, int rs2, int operation)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+	TCGv tcg_r1 = tcg_temp_new(tcg_ctx);
+	TCGv tcg_r2 = tcg_temp_new(tcg_ctx);
+	TCGv tcg_r3 = tcg_temp_new(tcg_ctx);
+	TCGv tcg_imm = tcg_temp_new(tcg_ctx);
+	TCGv tcg_temp = tcg_temp_new(tcg_ctx);
+	TCGv tcg_temp2 = tcg_temp_new(tcg_ctx);
+	TCGv insert = tcg_temp_new(tcg_ctx);
+
+	TCGLabel *cont;
+	TCGLabel *end;
+	TCGLabel *set;
+
+	int int_imm = rs1;
+	int int_rs3;
+	int int_cond;
+	int pos;
+	int lsb;
+	int msb;
+	int width;
+	int mask;
+	int group;
+
+	gen_get_gpr(tcg_ctx, tcg_r1, rs1);
+	gen_get_gpr(tcg_ctx, tcg_r2, rs2);
+
+	switch(operation) {
+
+		case OPC_RH850_BINS:
+
+			group = extract32(ctx->opcode, 21, 2);
+
+			mask = 0;
+			pos = extract32(ctx->opcode, 17, 3) | (extract32(ctx->opcode, 27, 1) << 3);
+			lsb = pos;
+
+			msb = extract32(ctx->opcode, 28, 4);
+			width = extract32(ctx->opcode, 28, 4) - pos + 1;
+
+			switch(group){
+			case 0:			//bins0
+				pos += 16;
+				break;
+			case 1:			//bins1
+				width += 16;
+				msb+=16;
+				break;
+			case 2:			//bins2
+				break;
+			}
+
+			if(msb<lsb){
+				tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, tcg_r2, 0x0);
+				tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_LT, cpu_SF, tcg_r2, 0x0);
+				tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+				break;
+			}
+
+			for(int i = 0; i < width; i++){
+				mask = mask | (0x1 << i);
+			}
+
+			tcg_gen_andi_i32(tcg_ctx, insert, tcg_r1, mask);		//insert has the bits from reg1
+
+			tcg_gen_movi_i32(tcg_ctx, tcg_temp, mask);
+			tcg_gen_shli_i32(tcg_ctx, tcg_temp, tcg_temp, pos);	//inverting and shifting the mask
+			tcg_gen_not_i32(tcg_ctx, tcg_temp, tcg_temp);		//for deletion of bits in reg2
+
+			tcg_gen_and_i32(tcg_ctx, tcg_r2, tcg_r2, tcg_temp);	//deleting bits that will be replaced
+			tcg_gen_shli_i32(tcg_ctx, insert, insert, pos);		//shifting bits to right position
+			tcg_gen_or_i32(tcg_ctx, tcg_r2, tcg_r2, insert);		//placing bits into reg2
+
+			gen_set_gpr(tcg_ctx, rs2, tcg_r2);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, tcg_r2, 0x0);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_LT, cpu_SF, tcg_r2, 0x0);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+			break;
+
+		case OPC_RH850_BSH_reg2_reg3: {
+
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv count_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv temp_local = tcg_temp_local_new_i32(tcg_ctx);
+
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			tcg_gen_mov_tl(tcg_ctx, tcg_temp2, tcg_r2);
+			tcg_gen_movi_i32(tcg_ctx, tcg_r3, 0x0);
+
+			tcg_gen_andi_tl(tcg_ctx, tcg_temp, tcg_temp2, 0xff000000);
+			tcg_gen_shri_tl(tcg_ctx, tcg_temp, tcg_temp, 0x8);
+			tcg_gen_or_tl(tcg_ctx, tcg_r3, tcg_r3, tcg_temp);
+
+			tcg_gen_andi_tl(tcg_ctx, tcg_temp, tcg_temp2, 0x00ff0000);
+			tcg_gen_shli_tl(tcg_ctx, tcg_temp, tcg_temp, 0x8);
+			tcg_gen_or_tl(tcg_ctx, tcg_r3, tcg_r3, tcg_temp);
+
+			tcg_gen_andi_tl(tcg_ctx, tcg_temp, tcg_temp2, 0x0000ff00);
+			tcg_gen_shri_tl(tcg_ctx, tcg_temp, tcg_temp, 0x8);
+			tcg_gen_or_tl(tcg_ctx, tcg_r3, tcg_r3, tcg_temp);
+
+			tcg_gen_andi_tl(tcg_ctx, tcg_temp, tcg_temp2, 0x000000ff);
+			tcg_gen_shli_tl(tcg_ctx, tcg_temp, tcg_temp, 0x8);
+			tcg_gen_or_tl(tcg_ctx, tcg_r3, tcg_r3, tcg_temp);
+
+			gen_set_gpr(tcg_ctx, int_rs3, tcg_r3);
+
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+			tcg_gen_mov_i32(tcg_ctx, r3_local, tcg_r3);
+
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+			set = gen_new_label(tcg_ctx);
+			tcg_gen_andi_i32(tcg_ctx, temp_local, r3_local, 0x0000ffff);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, temp_local, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, r3_local, 0x1f);
+
+			tcg_gen_movi_i32(tcg_ctx, count_local, 0x0);
+
+			tcg_gen_andi_i32(tcg_ctx, temp_local, r3_local, 0x000000ff);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, temp_local, 0x0, set);
+			tcg_gen_andi_i32(tcg_ctx, temp_local, r3_local, 0x0000ff00);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, temp_local, 0x0, set);
+
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, set);////
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x1);
+
+			gen_set_label(tcg_ctx, end);////
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r3_local);
+            tcg_temp_free(tcg_ctx, count_local);
+            tcg_temp_free(tcg_ctx, temp_local);
+		}	break;
+
+		case OPC_RH850_BSW_reg2_reg3: {
+
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv count_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv temp_local = tcg_temp_local_new_i32(tcg_ctx);
+
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+			set = gen_new_label(tcg_ctx);
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, tcg_r3,int_rs3);
+			tcg_gen_bswap32_i32(tcg_ctx, tcg_r3, tcg_r2);
+			gen_set_gpr(tcg_ctx, int_rs3, tcg_r3);
+
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+			tcg_gen_mov_i32(tcg_ctx, r3_local, tcg_r3);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r3_local, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, r3_local, 0x1f);
+
+			tcg_gen_movi_i32(tcg_ctx, count_local, 0x0);
+
+			gen_set_label(tcg_ctx, cont);////
+
+			tcg_gen_andi_i32(tcg_ctx, temp_local, r3_local, 0x000000ff);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, temp_local, 0x0, set);////
+			tcg_gen_addi_i32(tcg_ctx, count_local, count_local, 0x1);
+			tcg_gen_shri_i32(tcg_ctx, r3_local, r3_local, 0x8);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, count_local, 0x4, cont);////
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, set);
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x1);
+
+			gen_set_label(tcg_ctx, end);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r3_local);
+            tcg_temp_free(tcg_ctx, count_local);
+            tcg_temp_free(tcg_ctx, temp_local);
+		}
+			break;
+
+		case OPC_RH850_CMOV_cccc_reg1_reg2_reg3: {
+
+			TCGv r1_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new_i32(tcg_ctx);
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+
+			tcg_gen_mov_i32(tcg_ctx, r1_local, tcg_r1);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			int_cond = extract32(ctx->opcode, 17, 4);
+			TCGv condResult = condition_satisfied(tcg_ctx, int_cond);
+			cont = gen_new_label(tcg_ctx);
+
+			tcg_gen_mov_tl(tcg_ctx, r3_local, r2_local);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, condResult, 0x1, cont);
+			  tcg_gen_mov_tl(tcg_ctx, r3_local, r1_local);
+			gen_set_label(tcg_ctx, cont);
+
+			gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+
+            tcg_temp_free(tcg_ctx, condResult);
+			tcg_temp_free_i32(tcg_ctx, r1_local);
+			tcg_temp_free_i32(tcg_ctx, r2_local);
+			tcg_temp_free_i32(tcg_ctx, r3_local);
+		}
+			break;
+
+		case OPC_RH850_CMOV_cccc_imm5_reg2_reg3: {
+
+			TCGv r3_local = tcg_temp_local_new_i32(tcg_ctx);
+
+			if (int_imm & 0x10) {  // if is sign bit in imm5 set
+				int_imm = int_imm | 0xffffffe0;
+			}
+
+			int_cond = extract32(ctx->opcode, 17, 4);
+			TCGv condResult = condition_satisfied(tcg_ctx, int_cond);
+			cont = gen_new_label(tcg_ctx);
+
+			tcg_gen_mov_tl(tcg_ctx, r3_local, tcg_r2);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, condResult, 0x1, cont);
+			tcg_gen_movi_tl(tcg_ctx, r3_local, int_imm);
+
+			gen_set_label(tcg_ctx, cont);
+
+            int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+
+            tcg_temp_free(tcg_ctx, condResult);
+			tcg_temp_free_i32(tcg_ctx, r3_local);
+		}
+			break;
+
+		case OPC_RH850_HSH_reg2_reg3:
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_set_gpr(tcg_ctx, int_rs3, tcg_r2);
+
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, tcg_r2, 0x1f);
+			tcg_gen_andi_i32(tcg_ctx, tcg_temp, tcg_r2, 0x0000ffff);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, tcg_temp, 0x0);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_CYF, tcg_temp, 0x0);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+			break;
+
+		case OPC_RH850_HSW_reg2_reg3: {
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv temp_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv temp2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv temp3_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv count_local = tcg_temp_local_new_i32(tcg_ctx);
+
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+			set = gen_new_label(tcg_ctx);
+
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, r3_local,int_rs3);
+
+			tcg_gen_andi_tl(tcg_ctx, temp_local, r2_local, 0xffff);
+			tcg_gen_shli_tl(tcg_ctx, temp_local, temp_local, 0x10);
+			tcg_gen_andi_tl(tcg_ctx, temp2_local, r2_local, 0xffff0000);
+			tcg_gen_shri_tl(tcg_ctx, temp2_local, temp2_local, 0x10);
+
+			tcg_gen_or_tl(tcg_ctx, r3_local, temp2_local, temp_local);
+			gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r3_local, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, r3_local, 0x1f);
+
+			tcg_gen_movi_i32(tcg_ctx, count_local, 0x0);
+
+			gen_set_label(tcg_ctx, cont);
+
+			tcg_gen_andi_i32(tcg_ctx, temp3_local, r3_local, 0x0000ffff);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, temp3_local, 0x0, set);
+			tcg_gen_andi_i32(tcg_ctx, temp3_local, r3_local, 0xffff0000);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, temp3_local, 0x0, set);
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, set);////
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x1);
+
+			gen_set_label(tcg_ctx, end);////
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r3_local);
+            tcg_temp_free(tcg_ctx, count_local);
+            tcg_temp_free(tcg_ctx, temp_local);
+            tcg_temp_free(tcg_ctx, temp2_local);
+            tcg_temp_free(tcg_ctx, temp3_local);
+		}
+			break;
+
+		case OPC_RH850_ROTL_imm5_reg2_reg3:
+		{
+			TCGv r3_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv imm_local = tcg_temp_local_new_i32(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+
+			tcg_gen_movi_tl(tcg_ctx, tcg_imm, int_imm);
+			tcg_gen_ext8u_tl(tcg_ctx, tcg_imm, tcg_imm);
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, tcg_r3,int_rs3);
+			tcg_gen_rotl_tl(tcg_ctx, tcg_r3, tcg_r2, tcg_imm);
+			gen_set_gpr(tcg_ctx, int_rs3, tcg_r3);
+
+			tcg_gen_andi_i32(tcg_ctx, cpu_CYF, tcg_r3, 0x1);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, tcg_r3, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, tcg_r3, 0x1f);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+			tcg_gen_mov_i32(tcg_ctx, r3_local, tcg_r3);
+			tcg_gen_mov_i32(tcg_ctx, imm_local, tcg_imm);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, tcg_imm, 0x0, cont);
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+			gen_set_label(tcg_ctx, cont);
+
+            tcg_temp_free(tcg_ctx, r3_local);
+            tcg_temp_free(tcg_ctx, imm_local);
+		}	break;
+
+		case OPC_RH850_ROTL_reg1_reg2_reg3:
+		{
+			TCGv r3_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r1_local = tcg_temp_local_new_i32(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, tcg_r3,int_rs3);
+			tcg_gen_rotl_tl(tcg_ctx, tcg_r3, tcg_r2, tcg_r1);
+			gen_set_gpr(tcg_ctx,  int_rs3, tcg_r3);
+
+			tcg_gen_andi_i32(tcg_ctx, cpu_CYF, tcg_r3, 0x1);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, tcg_r3, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, tcg_r3, 0x1f);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+			tcg_gen_mov_i32(tcg_ctx, r3_local, tcg_r3);
+			tcg_gen_mov_i32(tcg_ctx, r1_local, tcg_r1);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, tcg_r1, 0x0, cont);
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+			gen_set_label(tcg_ctx, cont);
+
+            tcg_temp_free(tcg_ctx, r3_local);
+            tcg_temp_free(tcg_ctx, r1_local);
+		}	break;
+
+		case OPC_RH850_SAR_reg1_reg2: {
+
+			TCGv r1_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+
+			tcg_gen_mov_i32(tcg_ctx, r1_local, tcg_r1);
+			tcg_gen_andi_i32(tcg_ctx, r1_local, r1_local, 0x1f);	//shift by value of lower 5 bits of reg1
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, r1_local, 0x0, cont);
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, cont);
+
+			tcg_gen_subi_i32(tcg_ctx, r1_local, r1_local, 0x1);	//shift by r1-1
+
+			tcg_gen_sar_i32(tcg_ctx, r2_local, r2_local, r1_local);
+			tcg_gen_andi_i32(tcg_ctx, cpu_CYF, r2_local, 0x1);	//LSB here is the last bit to be shifted
+			tcg_gen_sari_i32(tcg_ctx, r2_local, r2_local, 0x1);
+
+			gen_set_label(tcg_ctx, end);
+
+			gen_set_gpr(tcg_ctx, rs2, r2_local);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, r2_local, 0x1f);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r1_local);
+		}
+			break;
+
+		case OPC_RH850_SAR_imm5_reg2: {
+
+			TCGv r1_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+
+			tcg_gen_movi_tl(tcg_ctx, r1_local, int_imm);
+			tcg_gen_ext8u_i32(tcg_ctx, r1_local, r1_local);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, r1_local, 0x0, cont);
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, cont);
+
+			tcg_gen_subi_i32(tcg_ctx, r1_local, r1_local, 0x1);	//shift by one less
+			tcg_gen_sar_i32(tcg_ctx, r2_local, r2_local, r1_local);
+			tcg_gen_andi_i32(tcg_ctx, cpu_CYF, r2_local, 0x1);	//LSB here is the last bit to be shifted
+			tcg_gen_sari_i32(tcg_ctx, r2_local, r2_local, 0x1);
+
+			gen_set_label(tcg_ctx, end);
+
+			gen_set_gpr(tcg_ctx, rs2, r2_local);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, r2_local, 0x1f);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+			tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r1_local);
+		}
+			break;
+
+		case OPC_RH850_SAR_reg1_reg2_reg3: {
+
+			TCGv r1_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new_i32(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+
+			tcg_gen_mov_i32(tcg_ctx, r1_local, tcg_r1);
+			tcg_gen_andi_i32(tcg_ctx, r1_local, r1_local, 0x1f);	//shift by only lower 5 bits of reg1
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, r3_local, int_rs3);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, r1_local, 0x0, cont);	//is non-shift?
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+			tcg_gen_mov_i32(tcg_ctx, r3_local, r2_local);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, cont);
+
+
+			tcg_gen_subi_i32(tcg_ctx, r1_local, r1_local, 0x1);	//shift by one less
+			tcg_gen_sar_i32(tcg_ctx, r3_local, r2_local, r1_local);
+			tcg_gen_andi_i32(tcg_ctx, cpu_CYF, r3_local, 0x1);	//LSB here is the last bit to be shifted
+			tcg_gen_sari_i32(tcg_ctx, r3_local, r3_local, 0x1);
+
+			gen_set_label(tcg_ctx, end);
+
+			gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r3_local, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, r3_local, 0x1f);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+            tcg_temp_free(tcg_ctx, r3_local);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r1_local);
+		}
+			break;
+
+		case OPC_RH850_SASF_cccc_reg2: {
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv operand_local = tcg_temp_local_new_i32(tcg_ctx);
+
+			int_cond = extract32(ctx->opcode,0,4);
+			TCGv condResult = condition_satisfied(tcg_ctx, int_cond);
+			cont = gen_new_label(tcg_ctx);
+
+			tcg_gen_shli_tl(tcg_ctx, r2_local, tcg_r2, 0x1);
+
+			tcg_gen_movi_i32(tcg_ctx, operand_local, 0x00000000);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, condResult, 0x1, cont);
+            tcg_gen_movi_i32(tcg_ctx, operand_local, 0x00000001);
+
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_or_tl(tcg_ctx, r2_local, r2_local, operand_local);
+
+			gen_set_gpr(tcg_ctx, rs2, r2_local);
+
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, operand_local);
+            tcg_temp_free(tcg_ctx, condResult);
+		}
+			break;
+
+		case OPC_RH850_SETF_cccc_reg2:{
+
+			TCGv operand_local = tcg_temp_local_new_i32(tcg_ctx);
+			int_cond = extract32(ctx->opcode,0,4);
+			TCGv condResult = condition_satisfied(tcg_ctx, int_cond);
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, condResult, 0x1, cont);
+			tcg_gen_movi_i32(tcg_ctx, operand_local, 0x00000001);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_movi_i32(tcg_ctx, operand_local, 0x00000000);
+			
+			gen_set_label(tcg_ctx, end);
+			gen_set_gpr(tcg_ctx, rs2, operand_local);
+
+			tcg_temp_free(tcg_ctx, condResult);
+			tcg_temp_free(tcg_ctx, operand_local);
+		}
+			break;
+
+		case OPC_RH850_SHL_reg1_reg2: {
+
+			TCGv r1_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv temp_local = tcg_temp_local_new_i32(tcg_ctx);
+
+			tcg_gen_mov_i32(tcg_ctx, r1_local, tcg_r1);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+
+			tcg_gen_andi_i32(tcg_ctx, r1_local, r1_local, 0x1f); 	//get only lower 5 bits
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, r1_local, 0x0, cont);
+
+			tcg_gen_subi_i32(tcg_ctx, temp_local, r1_local, 0x1); 	// shifting for [r1]-1
+			tcg_gen_shl_tl(tcg_ctx, r2_local, r2_local, temp_local);
+
+			tcg_gen_shri_i32(tcg_ctx, cpu_CYF, r2_local, 0x1f);	// checking the last bit to shift
+			tcg_gen_shli_i32(tcg_ctx, r2_local, r2_local, 0x1);		// shifting for that remaining 1
+
+			gen_set_gpr(tcg_ctx, rs2, r2_local);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+
+			gen_set_label(tcg_ctx, end);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, r2_local, 0x1f);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+            tcg_temp_free(tcg_ctx, r1_local);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, temp_local);
+		}
+			break;
+
+		case OPC_RH850_SHL_imm5_reg2: {
+
+			TCGv r1_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv temp_local = tcg_temp_local_new_i32(tcg_ctx);
+
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			tcg_gen_movi_tl(tcg_ctx, r1_local, int_imm);
+			tcg_gen_ext8u_tl(tcg_ctx, r1_local, r1_local);
+
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, r1_local, 0x0, cont);
+
+			tcg_gen_subi_i32(tcg_ctx, temp_local, r1_local, 0x1);
+			tcg_gen_shl_tl(tcg_ctx, r2_local, r2_local, temp_local);
+			tcg_gen_shri_i32(tcg_ctx, cpu_CYF, r2_local, 0x1f);
+			tcg_gen_shli_tl(tcg_ctx, r2_local, r2_local, 0x1);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+
+			gen_set_label(tcg_ctx, end);
+			gen_set_gpr(tcg_ctx, rs2, r2_local);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, r2_local, 0x1f);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+			tcg_temp_free(tcg_ctx, r1_local);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, temp_local);
+		}
+			break;
+
+		case OPC_RH850_SHL_reg1_reg2_reg3: {
+
+			TCGv r1_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv temp_local = tcg_temp_local_new_i32(tcg_ctx);
+
+			tcg_gen_mov_i32(tcg_ctx, r1_local, tcg_r1);
+			tcg_gen_andi_i32(tcg_ctx, r1_local, r1_local, 0x1f);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, r3_local,int_rs3);
+
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, r1_local, 0x0, cont); 	// when reg1 = 0, do not shift
+
+			tcg_gen_subi_i32(tcg_ctx, temp_local, r1_local, 0x1);
+			tcg_gen_shl_tl(tcg_ctx, r3_local, r2_local, temp_local);
+
+			tcg_gen_shri_i32(tcg_ctx, cpu_CYF, r3_local, 0x1f);
+			tcg_gen_shli_tl(tcg_ctx, r3_local, r3_local, 0x1);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_mov_i32(tcg_ctx, r3_local, r2_local);
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+
+			gen_set_label(tcg_ctx, end);
+			gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r3_local, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, r3_local, 0x1f);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+            tcg_temp_free(tcg_ctx, r1_local);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r3_local);
+            tcg_temp_free(tcg_ctx, temp_local);
+		}
+			break;
+
+		case OPC_RH850_SHR_reg1_reg2: {
+
+			TCGv r1_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv temp_local = tcg_temp_local_new_i32(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+
+			tcg_gen_mov_i32(tcg_ctx, r1_local, tcg_r1);
+			tcg_gen_andi_i32(tcg_ctx, r1_local, r1_local, 0x1f); //
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, r1_local, 0x0, cont); //checking for non-shift
+
+			tcg_gen_subi_i32(tcg_ctx, temp_local, r1_local, 0x1); 	// shifting for [r1]-1
+			tcg_gen_shr_tl(tcg_ctx, r2_local, r2_local, temp_local);
+
+
+			tcg_gen_andi_i32(tcg_ctx, cpu_CYF, r2_local, 0x1);	// checking the last bit to shift (LSB)
+			tcg_gen_shri_i32(tcg_ctx, r2_local, r2_local, 0x1);
+
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+
+			gen_set_label(tcg_ctx, end);
+			gen_set_gpr(tcg_ctx, rs2, r2_local);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, r2_local, 0x1f);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+			tcg_temp_free(tcg_ctx, r1_local);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, temp_local);
+		}
+			break;
+
+		case OPC_RH850_SHR_imm5_reg2: {
+
+			TCGv r1_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv temp_local = tcg_temp_local_new_i32(tcg_ctx);
+
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			tcg_gen_movi_tl(tcg_ctx, r1_local, int_imm);
+			tcg_gen_ext8u_tl(tcg_ctx, r1_local, r1_local);
+
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, r1_local, 0x0, cont); //checking for non-shift
+
+			tcg_gen_subi_i32(tcg_ctx, temp_local, r1_local, 0x1); 	// shifting for [r1]-1
+			tcg_gen_shr_tl(tcg_ctx, r2_local, r2_local, temp_local);
+
+			tcg_gen_andi_i32(tcg_ctx, cpu_CYF, r2_local, 0x1);	// checking the last bit to shift (LSB)
+			tcg_gen_shri_i32(tcg_ctx, r2_local, r2_local, 0x1);
+
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+
+			gen_set_label(tcg_ctx, end);
+			gen_set_gpr(tcg_ctx, rs2, r2_local);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, r2_local, 0x1f);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+			tcg_temp_free(tcg_ctx, r1_local);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, temp_local);
+		}
+			break;
+
+		case OPC_RH850_SHR_reg1_reg2_reg3: {
+
+			TCGv r1_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new_i32(tcg_ctx);
+			TCGv temp_local = tcg_temp_local_new_i32(tcg_ctx);
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+
+			tcg_gen_mov_i32(tcg_ctx, r1_local, tcg_r1);
+			tcg_gen_andi_i32(tcg_ctx, r1_local, r1_local, 0x1f);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, r3_local, int_rs3);
+
+
+
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, r1_local, 0x0, cont); //checking for non-shift
+
+			tcg_gen_subi_i32(tcg_ctx, temp_local, r1_local, 0x1); 	// shifting for [r1]-1
+			tcg_gen_shr_tl(tcg_ctx, r3_local, r2_local, temp_local);
+
+			tcg_gen_andi_i32(tcg_ctx, cpu_CYF, r3_local, 0x1);	// checking the last bit to shift (LSB)
+			tcg_gen_shri_i32(tcg_ctx, r3_local, r3_local, 0x1);
+
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, cont);
+			tcg_gen_movi_i32(tcg_ctx, cpu_CYF, 0x0);
+			tcg_gen_mov_i32(tcg_ctx, r3_local, r2_local);
+
+			gen_set_label(tcg_ctx, end);
+			gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r3_local, 0x0);
+			tcg_gen_shri_i32(tcg_ctx, cpu_SF, r3_local, 0x1f);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+
+            tcg_temp_free(tcg_ctx, r1_local);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r3_local);
+            tcg_temp_free(tcg_ctx, temp_local);
+		}
+			break;
+
+		case OPC_RH850_SXB_reg1:
+			tcg_gen_andi_tl(tcg_ctx, tcg_r1, tcg_r1,0xFF);
+			tcg_gen_ext8s_tl(tcg_ctx, tcg_r1, tcg_r1);
+			gen_set_gpr(tcg_ctx, rs1, tcg_r1);
+			break;
+
+		case OPC_RH850_SXH_reg1:
+			tcg_gen_andi_tl(tcg_ctx, tcg_r1, tcg_r1,0xFFFF);
+			tcg_gen_ext16s_tl(tcg_ctx, tcg_r1, tcg_r1);
+			gen_set_gpr(tcg_ctx, rs1, tcg_r1);
+			break;
+
+		case OPC_RH850_ZXH_reg1:
+			tcg_gen_andi_tl(tcg_ctx, tcg_r1, tcg_r1,0xFFFF);
+			tcg_gen_ext16u_tl(tcg_ctx, tcg_r1, tcg_r1);
+			gen_set_gpr(tcg_ctx, rs1, tcg_r1);
+			break;
+
+		case OPC_RH850_ZXB_reg1:
+			tcg_gen_andi_tl(tcg_ctx, tcg_r1, tcg_r1,0xFF);
+			tcg_gen_ext8u_tl(tcg_ctx, tcg_r1, tcg_r1);
+			gen_set_gpr(tcg_ctx, rs1, tcg_r1);
+			break;
+	}
+
+	tcg_temp_free(tcg_ctx, tcg_r1);
+	tcg_temp_free(tcg_ctx, tcg_r2);
+	tcg_temp_free(tcg_ctx, tcg_r3);
+	tcg_temp_free(tcg_ctx, tcg_imm);
+	tcg_temp_free(tcg_ctx, tcg_temp);
+	tcg_temp_free(tcg_ctx, tcg_temp2);
+    tcg_temp_free(tcg_ctx, insert);
+}
+
+static void gen_bit_search(DisasContext *ctx, int rs2, int operation)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+	TCGv tcg_r2 = tcg_temp_new(tcg_ctx);
+	TCGv tcg_r3 = tcg_temp_new(tcg_ctx);
+	int int_rs3;
+	int_rs3 = extract32(ctx->opcode, 27, 5);
+
+	gen_get_gpr(tcg_ctx, tcg_r2, rs2);
+	gen_get_gpr(tcg_ctx, tcg_r3, int_rs3);
+
+	TCGLabel *end;
+	TCGLabel *found;
+	TCGLabel *loop;
+
+	switch(operation){
+		case OPC_RH850_SCH0L_reg2_reg3: {
+
+			TCGv foundFlag = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new(tcg_ctx);
+			TCGv result = tcg_temp_local_new(tcg_ctx);
+			TCGv check = tcg_temp_local_new(tcg_ctx);
+			TCGv count = tcg_temp_local_new(tcg_ctx);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+			tcg_gen_mov_i32(tcg_ctx, r3_local, tcg_r3);
+			tcg_gen_movi_i32(tcg_ctx, count, 0x0);
+
+			end = gen_new_label(tcg_ctx);
+			found = gen_new_label(tcg_ctx);
+			loop = gen_new_label(tcg_ctx);
+
+			gen_set_label(tcg_ctx, loop);//---------------------------------------------------
+
+			tcg_gen_shl_i32(tcg_ctx, check, r2_local, count);
+			tcg_gen_ori_i32(tcg_ctx, check, check, 0x7fffffff);	// check MSB bit
+			tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_EQ, check, 0x7fffffff, found);
+
+			tcg_gen_addi_i32(tcg_ctx, count, count, 0x1);
+			tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, count, 0x20, loop);//--------------------
+
+			tcg_gen_movi_i32(tcg_ctx, result, 0x0);
+			tcg_gen_movi_i32(tcg_ctx, foundFlag, 0x0);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, found);
+			tcg_gen_movi_i32(tcg_ctx, foundFlag, 0x1);
+			tcg_gen_addi_i32(tcg_ctx, result, count, 0x1);
+
+			gen_set_label(tcg_ctx, end);
+
+			gen_set_gpr(tcg_ctx, int_rs3, result);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, foundFlag, 0x1); //setting Z if not found
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SF, 0x0);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_CYF, r2_local, 0xfffffffe); //setting CY if found at the end
+
+            tcg_temp_free(tcg_ctx, foundFlag);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r3_local);
+			tcg_temp_free(tcg_ctx, check);
+            tcg_temp_free(tcg_ctx, count);
+			tcg_temp_free(tcg_ctx, result);
+		}	break;
+
+		case OPC_RH850_SCH0R_reg2_reg3: {
+
+			TCGv foundFlag = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new(tcg_ctx);
+			TCGv result = tcg_temp_local_new(tcg_ctx);
+			TCGv check = tcg_temp_local_new(tcg_ctx);
+			TCGv count = tcg_temp_local_new(tcg_ctx);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+			tcg_gen_mov_i32(tcg_ctx, r3_local, tcg_r3);
+			tcg_gen_movi_i32(tcg_ctx, count, 0x0);
+
+			end = gen_new_label(tcg_ctx);
+			found = gen_new_label(tcg_ctx);
+			loop = gen_new_label(tcg_ctx);
+
+			gen_set_label(tcg_ctx, loop);//---------------------------------------------------
+
+			tcg_gen_shr_i32(tcg_ctx, check, r2_local, count);
+			tcg_gen_ori_i32(tcg_ctx, check, check, 0xfffffffe);	// check MSB bit
+			tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_EQ, check, 0xfffffffe, found);
+
+			tcg_gen_addi_i32(tcg_ctx, count, count, 0x1);
+			tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, count, 0x20, loop);//--------------------
+
+			tcg_gen_movi_i32(tcg_ctx, result, 0x0);
+			tcg_gen_movi_i32(tcg_ctx, foundFlag, 0x0);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, found);
+			tcg_gen_movi_i32(tcg_ctx, foundFlag, 0x1);
+			tcg_gen_addi_i32(tcg_ctx, result, count, 0x1);
+
+			gen_set_label(tcg_ctx, end);
+
+			gen_set_gpr(tcg_ctx, int_rs3, result);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, foundFlag, 0x1); //setting Z if not found
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SF, 0x0);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_CYF, r2_local, 0x7fffffff);
+
+            tcg_temp_free(tcg_ctx, foundFlag);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r3_local);
+            tcg_temp_free(tcg_ctx, check);
+            tcg_temp_free(tcg_ctx, count);
+            tcg_temp_free(tcg_ctx, result);
+		}	break;
+
+		case OPC_RH850_SCH1L_reg2_reg3: {
+
+			TCGv foundFlag = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new(tcg_ctx);
+			TCGv result = tcg_temp_local_new(tcg_ctx);
+			TCGv check = tcg_temp_local_new(tcg_ctx);
+			TCGv count = tcg_temp_local_new(tcg_ctx);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+			tcg_gen_mov_i32(tcg_ctx, r3_local, tcg_r3);
+			tcg_gen_movi_i32(tcg_ctx, count, 0x0);
+
+			end = gen_new_label(tcg_ctx);
+			found = gen_new_label(tcg_ctx);
+			loop = gen_new_label(tcg_ctx);
+
+			gen_set_label(tcg_ctx, loop);//---------------------------------------------------
+
+			tcg_gen_shl_i32(tcg_ctx, check, r2_local, count);
+			tcg_gen_andi_i32(tcg_ctx, check, check, 0x80000000);	// check MSB bit
+			tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_EQ, check, 0x80000000, found);
+
+			tcg_gen_addi_i32(tcg_ctx, count, count, 0x1);
+			tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, count, 0x20, loop);//--------------------
+
+			tcg_gen_movi_i32(tcg_ctx, result, 0x0);
+			tcg_gen_movi_i32(tcg_ctx, foundFlag, 0x0);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, found);
+			tcg_gen_movi_i32(tcg_ctx, foundFlag, 0x1);
+			tcg_gen_addi_i32(tcg_ctx, result, count, 0x1);
+
+			gen_set_label(tcg_ctx, end);
+
+			gen_set_gpr(tcg_ctx, int_rs3, result);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, foundFlag, 0x1); //setting Z if not found
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SF, 0x0);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_CYF, r2_local, 0x1);
+
+            tcg_temp_free(tcg_ctx, foundFlag);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r3_local);
+            tcg_temp_free(tcg_ctx, check);
+            tcg_temp_free(tcg_ctx, count);
+            tcg_temp_free(tcg_ctx, result);
+		}	break;
+
+		case OPC_RH850_SCH1R_reg2_reg3: {
+
+			TCGv foundFlag = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new(tcg_ctx);
+			TCGv result = tcg_temp_local_new(tcg_ctx);
+			TCGv check = tcg_temp_local_new(tcg_ctx);
+			TCGv count = tcg_temp_local_new(tcg_ctx);
+
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+			tcg_gen_mov_i32(tcg_ctx, r3_local, tcg_r3);
+			tcg_gen_movi_i32(tcg_ctx, count, 0x0);
+
+			end = gen_new_label(tcg_ctx);
+			found = gen_new_label(tcg_ctx);
+			loop = gen_new_label(tcg_ctx);
+
+			gen_set_label(tcg_ctx, loop);//---------------------------------------------------
+
+			tcg_gen_shr_i32(tcg_ctx, check, r2_local, count);
+			tcg_gen_andi_i32(tcg_ctx, check, check, 0x1);	// check MSB bit
+			tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_EQ, check, 0x1, found);
+
+			tcg_gen_addi_i32(tcg_ctx, count, count, 0x1);
+			tcg_gen_brcondi_tl(tcg_ctx, TCG_COND_NE, count, 0x20, loop);//--------------------
+
+			tcg_gen_movi_i32(tcg_ctx, result, 0x0);
+			tcg_gen_movi_i32(tcg_ctx, foundFlag, 0x0);
+			tcg_gen_br(tcg_ctx, end);
+
+			gen_set_label(tcg_ctx, found);
+			tcg_gen_movi_i32(tcg_ctx, foundFlag, 0x1);
+			tcg_gen_addi_i32(tcg_ctx, result, count, 0x1);
+
+			gen_set_label(tcg_ctx, end);
+
+			gen_set_gpr(tcg_ctx, int_rs3, result);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, foundFlag, 0x1); //setting Z if not found
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x0);
+			tcg_gen_movi_i32(tcg_ctx, cpu_SF, 0x0);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_CYF, r2_local, 0x80000000);
+
+            tcg_temp_free(tcg_ctx, foundFlag);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r3_local);
+            tcg_temp_free(tcg_ctx, check);
+            tcg_temp_free(tcg_ctx, count);
+            tcg_temp_free(tcg_ctx, result);
+		}	break;
+	}
+
+	tcg_temp_free(tcg_ctx, tcg_r2);
+    tcg_temp_free(tcg_ctx, tcg_r3);
+}
+
+static void gen_divide(DisasContext *ctx, int rs1, int rs2, int operation)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+	TCGv tcg_r1 = tcg_temp_new(tcg_ctx);
+	TCGv tcg_r2 = tcg_temp_new(tcg_ctx);
+
+	gen_get_gpr(tcg_ctx, tcg_r1, rs1);
+	gen_get_gpr(tcg_ctx, tcg_r2, rs2);
+
+	int int_rs3;
+
+	TCGv tcg_r3 = tcg_temp_new(tcg_ctx);
+
+	switch(operation){
+
+		case OPC_RH850_DIV_reg1_reg2_reg3:{
+
+			TCGLabel *cont;
+			TCGLabel *end;
+			TCGLabel *fin;
+
+			TCGv r1_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new(tcg_ctx);
+
+			tcg_gen_mov_i32(tcg_ctx, r1_local, tcg_r1);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, tcg_r3, int_rs3);
+			tcg_gen_mov_i32(tcg_ctx, r3_local, tcg_r3);
+			TCGv overflowed = tcg_temp_local_new(tcg_ctx);
+			TCGv overflowed2 = tcg_temp_local_new(tcg_ctx);
+
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+			fin = gen_new_label(tcg_ctx);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_OVF, r1_local, 0x0);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, cpu_OVF, 0x1, cont); 		//if r1=0 jump to end
+
+			tcg_gen_movi_i32(tcg_ctx, r2_local, 0x80000000);
+			tcg_gen_br(tcg_ctx, fin);
+
+			gen_set_label(tcg_ctx, cont);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, overflowed, r2_local, 0x80000000);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, overflowed2, r1_local, 0xffffffff);
+			tcg_gen_and_i32(tcg_ctx, overflowed, overflowed, overflowed2);		//if both
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_OVF, overflowed, 0x1);	//are 1
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, cpu_OVF, 0x1, end);
+			tcg_gen_movi_i32(tcg_ctx, r2_local, 0x80000000);						//DO THIS
+			tcg_gen_movi_i32(tcg_ctx, r3_local, 0x0000);
+			gen_set_gpr(tcg_ctx, rs2, r2_local);			//write zeros if undefined
+			gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_LT, cpu_SF, r2_local, 0x0);
+			tcg_gen_br(tcg_ctx, fin);
+
+			gen_set_label(tcg_ctx, end);
+
+			tcg_gen_rem_i32(tcg_ctx, r3_local, r2_local, r1_local);
+			tcg_gen_div_i32(tcg_ctx, r2_local, r2_local, r1_local);
+
+			if(rs2==int_rs3){
+				gen_set_gpr(tcg_ctx, rs2, r3_local);
+			} else {
+				gen_set_gpr(tcg_ctx, rs2, r2_local);
+				gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+			}
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_LT, cpu_SF, r2_local, 0x0);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+
+			gen_set_label(tcg_ctx, fin);
+
+            tcg_temp_free(tcg_ctx, overflowed);
+            tcg_temp_free(tcg_ctx, overflowed2);
+            tcg_temp_free(tcg_ctx, r1_local);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r3_local);
+		}	break;
+
+		case OPC_RH850_DIVH_reg1_reg2:{
+
+			TCGLabel *cont;
+			TCGLabel *end;
+			TCGLabel *fin;
+
+			tcg_gen_andi_i32(tcg_ctx, tcg_r1, tcg_r1, 0x0000FFFF);
+			tcg_gen_ext16s_i32(tcg_ctx, tcg_r1, tcg_r1);
+
+			TCGv r1_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv overflowed = tcg_temp_local_new(tcg_ctx);
+			TCGv overflowed2 = tcg_temp_local_new(tcg_ctx);
+
+			tcg_gen_mov_i32(tcg_ctx, r1_local, tcg_r1);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+			fin = gen_new_label(tcg_ctx);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_OVF, r1_local, 0x0);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, cpu_OVF, 0x1, cont); 		//if r1=0 jump to cont
+			tcg_gen_br(tcg_ctx, fin);
+
+			gen_set_label(tcg_ctx, cont);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, overflowed, r2_local, 0x80000000);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, overflowed2, r1_local, 0xffffffff);
+			tcg_gen_and_i32(tcg_ctx, overflowed, overflowed, overflowed2);		//if both
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_OVF, overflowed, 0x1);	//are 1
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, cpu_OVF, 0x1, end);
+			tcg_gen_movi_i32(tcg_ctx, r2_local, 0x80000000);						//DO THIS
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x1);
+			gen_set_gpr(tcg_ctx, rs2, r2_local);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_LT, cpu_SF, r2_local, 0x0);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+			tcg_gen_br(tcg_ctx, fin);
+
+			gen_set_label(tcg_ctx, end);
+
+			tcg_gen_div_i32(tcg_ctx, r2_local, r2_local, r1_local);
+			gen_set_gpr(tcg_ctx, rs2, r2_local);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_LT, cpu_SF, r2_local, 0x0);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+
+			gen_set_label(tcg_ctx, fin);
+
+            tcg_temp_free(tcg_ctx, overflowed);
+            tcg_temp_free(tcg_ctx, overflowed2);
+            tcg_temp_free(tcg_ctx, r1_local);
+            tcg_temp_free(tcg_ctx, r2_local);
+		}	break;
+
+		case OPC_RH850_DIVH_reg1_reg2_reg3: {
+			// 0x80000000/0xffffffff=0x80000000; cpu_OVF=1, cpu_Z=1?
+			// reg2/0x0000=undefined; cpu_OVF=1
+			// if reg2==reg3; reg2=remainder
+
+			TCGLabel *cont;
+			TCGLabel *end;
+			TCGLabel *fin;
+
+			TCGv r1_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new(tcg_ctx);
+
+			tcg_gen_andi_i32(tcg_ctx, tcg_r1, tcg_r1, 0x0000FFFF);
+			tcg_gen_ext16s_i32(tcg_ctx, tcg_r1, tcg_r1);
+			tcg_gen_mov_i32(tcg_ctx, r1_local, tcg_r1);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, tcg_r3, int_rs3);
+			tcg_gen_mov_i32(tcg_ctx, r3_local, tcg_r3);
+			TCGv overflowed = tcg_temp_local_new(tcg_ctx);
+			TCGv overflowed2 = tcg_temp_local_new(tcg_ctx);
+
+			cont = gen_new_label(tcg_ctx);
+			end = gen_new_label(tcg_ctx);
+			fin = gen_new_label(tcg_ctx);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_OVF, r1_local, 0x0);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, cpu_OVF, 0x1, cont);
+			tcg_gen_br(tcg_ctx, fin);
+
+			gen_set_label(tcg_ctx, cont);	/////
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, overflowed, r2_local, 0x80000000);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, overflowed2, r1_local, 0xffffffff);
+			tcg_gen_and_i32(tcg_ctx, overflowed, overflowed, overflowed2);	// if result is 1, cpu_OVF = 1
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_OVF, overflowed, 0x1);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, cpu_OVF, 0x1, end);
+			tcg_gen_movi_i32(tcg_ctx, r2_local, 0x80000000);
+			tcg_gen_movi_i32(tcg_ctx, r3_local, 0x0000);
+			tcg_gen_movi_i32(tcg_ctx, cpu_OVF, 0x1);
+			gen_set_gpr(tcg_ctx, rs2, r2_local);
+			gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_LT, cpu_SF, r2_local, 0x0);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+			tcg_gen_br(tcg_ctx, fin);
+
+			gen_set_label(tcg_ctx, end);		/////
+
+			tcg_gen_rem_i32(tcg_ctx, r3_local, r2_local, r1_local);
+			tcg_gen_div_i32(tcg_ctx, r2_local, r2_local, r1_local);
+
+			if(rs2==int_rs3){
+				gen_set_gpr(tcg_ctx, rs2, r3_local);
+			} else {
+				gen_set_gpr(tcg_ctx, rs2, r2_local);
+				gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+			}
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_LT, cpu_SF, r2_local, 0x0);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+
+			gen_set_label(tcg_ctx, fin);		/////
+
+            tcg_temp_free(tcg_ctx, overflowed);
+            tcg_temp_free(tcg_ctx, overflowed2);
+            tcg_temp_free(tcg_ctx, r1_local);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r3_local);
+		}	break;
+
+		case OPC_RH850_DIVHU_reg1_reg2_reg3:{
+
+			TCGLabel *cont;
+			TCGLabel *fin;
+
+			TCGv r1_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new(tcg_ctx);
+
+			tcg_gen_andi_i32(tcg_ctx, tcg_r1, tcg_r1, 0x0000FFFF);
+			tcg_gen_ext16u_i32(tcg_ctx, tcg_r1, tcg_r1);
+			tcg_gen_mov_i32(tcg_ctx, r1_local, tcg_r1);
+
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, tcg_r3, int_rs3);
+			tcg_gen_mov_i32(tcg_ctx, r3_local, tcg_r3);
+
+			cont = gen_new_label(tcg_ctx);
+			fin = gen_new_label(tcg_ctx);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_OVF, r1_local, 0x0);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, cpu_OVF, 0x1, cont);
+			tcg_gen_br(tcg_ctx, fin);
+
+			gen_set_label(tcg_ctx, cont);	/////
+			tcg_gen_remu_i32(tcg_ctx, r3_local, r2_local, r1_local);
+			tcg_gen_divu_i32(tcg_ctx, r2_local, r2_local, r1_local);
+
+			if(rs2==int_rs3){
+				gen_set_gpr(tcg_ctx, rs2, r3_local);
+			} else {
+				gen_set_gpr(tcg_ctx, rs2, r2_local);
+				gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+			}
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_LT, cpu_SF, r2_local, 0x0);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+
+			gen_set_label(tcg_ctx, fin);		/////
+
+            tcg_temp_free(tcg_ctx, r1_local);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r3_local);
+		}
+			break;
+
+		case OPC_RH850_DIVU_reg1_reg2_reg3:{
+
+			// reg2/0x0000=undefined; cpu_OVF=1
+			// if reg2==reg3; reg2=remainder
+
+			TCGLabel *cont;
+			TCGLabel *fin;
+
+			TCGv r1_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r2_local = tcg_temp_local_new(tcg_ctx);
+			TCGv r3_local = tcg_temp_local_new(tcg_ctx);
+			TCGv check = tcg_temp_local_new(tcg_ctx);
+
+			tcg_gen_mov_i32(tcg_ctx, r1_local, tcg_r1);
+			tcg_gen_mov_i32(tcg_ctx, r2_local, tcg_r2);
+
+			int_rs3 = extract32(ctx->opcode, 27, 5);
+			gen_get_gpr(tcg_ctx, tcg_r3, int_rs3);
+			tcg_gen_mov_i32(tcg_ctx, r3_local, tcg_r3);
+
+			cont = gen_new_label(tcg_ctx);
+			fin = gen_new_label(tcg_ctx);
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_OVF, r1_local, 0x0);
+			tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, cpu_OVF, 0x1, cont);
+			tcg_gen_br(tcg_ctx, fin);
+
+			gen_set_label(tcg_ctx, cont);	/////
+
+			tcg_gen_remu_i32(tcg_ctx, r3_local, r2_local, r1_local);
+			tcg_gen_divu_i32(tcg_ctx, r2_local, r2_local, r1_local);
+
+			if(rs2==int_rs3){
+				gen_set_gpr(tcg_ctx, rs2, r3_local);
+			} else {
+				gen_set_gpr(tcg_ctx, rs2, r2_local);
+				gen_set_gpr(tcg_ctx, int_rs3, r3_local);
+			}
+
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, r2_local, 0x0);
+			tcg_gen_andi_i32(tcg_ctx, check, r2_local, 0x80000000);
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_SF, check, 0x80000000);
+
+			gen_set_label(tcg_ctx, fin);		/////
+
+            tcg_temp_free(tcg_ctx, r1_local);
+            tcg_temp_free(tcg_ctx, r2_local);
+            tcg_temp_free(tcg_ctx, r3_local);
+            tcg_temp_free(tcg_ctx, check);
+		}
+			break;
+	}
+
+	tcg_temp_free_i32(tcg_ctx, tcg_r1);
+	tcg_temp_free_i32(tcg_ctx, tcg_r2);
+	tcg_temp_free_i32(tcg_ctx, tcg_r3);
+}
+
+static void gen_branch(CPURH850State *env, DisasContext *ctx, uint32_t cond,
+                       int rs1, int rs2, target_long bimm)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+    TCGLabel *l = gen_new_label(tcg_ctx);
+    TCGv condOK = tcg_temp_new(tcg_ctx);
+    TCGv condResult = condition_satisfied(tcg_ctx, cond);
+    tcg_gen_movi_i32(tcg_ctx, condOK, 0x1);
+
+    tcg_gen_brcond_tl(tcg_ctx, TCG_COND_EQ, condResult, condOK, l);
+
+    tcg_temp_free(tcg_ctx, condResult);
+    tcg_temp_free(tcg_ctx, condOK);
+
+    gen_goto_tb_imm(ctx, 1, ctx->base.pc_next); // no jump, continue with next instr.
+    gen_set_label(tcg_ctx, l); /* branch taken */
+   	gen_goto_tb_imm(ctx, 0, ctx->pc + bimm);  // jump
+   	ctx->base.is_jmp = DISAS_TB_EXIT_ALREADY_GENERATED;
+}
+
+static void gen_jmp(DisasContext *ctx, int rs1, uint32_t disp32, int operation)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+    // disp32 is already generated when entering this function
+    int rs2, rs3;
+    TCGv link_addr = tcg_temp_new(tcg_ctx);
+    TCGv dest_addr = tcg_temp_new(tcg_ctx);
+
+    switch (operation)
+    {
+    /**
+     * Jump with immediate displacement.
+     * PC and disp32 are fixed and won't change at
+     * execution time, we can call gen_goto_tb_imm() with
+     * the computed destination address.
+     */
+    case OPC_RH850_JR_imm22:
+    case OPC_RH850_JR_imm32:
+    {
+        gen_goto_tb_imm(ctx, 0, ctx->pc + disp32);
+        ctx->base.is_jmp = DISAS_TB_EXIT_ALREADY_GENERATED;
+    }
+    break;
+
+    /**
+     * Jump with immediate displacement but store
+     * PC+4 first in reg2. We first call tcg_goto_tb(),
+     * update PC and reg2 and then issue an exit TB.
+     **/
+    case OPC_RH850_JARL_disp22_reg2:
+    {
+        rs2 = extract32(ctx->opcode, 11, 5);
+        tcg_gen_movi_i32(tcg_ctx, link_addr, ctx->pc);
+        tcg_gen_addi_i32(tcg_ctx, link_addr, link_addr, 0x4);
+        gen_set_gpr(tcg_ctx, rs2, link_addr);
+
+        /* Update pc */
+        tcg_gen_movi_i32(tcg_ctx, cpu_pc, ctx->pc + disp32);
+
+        /* Goto corresponding TB (indirect jump). */
+        ctx->base.is_jmp = DISAS_INDIRECT_JUMP;
+    }
+    break;
+
+        /**
+         * Jump with immediate displacement but store PC+6 first in reg1.
+         * We first call tcg_gen_goto_tb(), update PC and reg1 and then
+         * issue an exit TB.
+         **/
+
+    case OPC_RH850_JARL_disp32_reg1:
+    {
+        gen_goto_tb_rl(ctx, 0, rs1, 6, ctx->pc + disp32);
+        ctx->base.is_jmp = DISAS_TB_EXIT_ALREADY_GENERATED;
+    }
+    break;
+
+        /**
+         * This is a pure indirect call that will move GR[reg1] into PC,
+         * so we need to process in a different way.
+         **/
+
+    case OPC_RH850_JARL_reg1_reg3:
+    {
+        /* Get reg1 content into dest_addr. */
+        gen_get_gpr(tcg_ctx, dest_addr, rs1);
+
+        /* Get reg3 index, and store PC+4 in it. */
+        rs3 = extract32(ctx->opcode, 27, 5);
+        tcg_gen_movi_i32(tcg_ctx, link_addr, ctx->pc);
+        tcg_gen_addi_i32(tcg_ctx, link_addr, link_addr, 0x4);
+        gen_set_gpr(tcg_ctx, rs3, link_addr);
+
+        /* Update pc */
+        tcg_gen_andi_i32(tcg_ctx, dest_addr, dest_addr, 0xfffffffe);
+        tcg_gen_mov_i32(tcg_ctx, cpu_pc, dest_addr);
+
+        /* Goto corresponding TB (indirect jump). */
+        ctx->base.is_jmp = DISAS_INDIRECT_JUMP;
+    }
+    break;
+
+    default: // JMP instruction
+    {
+        /* Get reg1 into dest_addr. */
+        gen_get_gpr(tcg_ctx, dest_addr, rs1);
+
+        /* Apply displacement if provided. */
+        if (disp32 != 0)
+        {
+            tcg_gen_addi_i32(tcg_ctx, dest_addr, dest_addr, disp32);
+        }
+
+        /* Align and update PC. */
+        tcg_gen_andi_i32(tcg_ctx, dest_addr, dest_addr, 0xfffffffe);
+        tcg_gen_mov_i32(tcg_ctx, cpu_pc, dest_addr);
+
+        /* Indirect jump. */
+        ctx->base.is_jmp = DISAS_INDIRECT_JUMP;
+    }
+    break;
+    }
+
+    /* Free temporary values. */
+    tcg_temp_free_i32(tcg_ctx, link_addr);
+    tcg_temp_free_i32(tcg_ctx, dest_addr);
+}
+
+static void gen_loop(DisasContext *ctx, int rs1, int32_t disp16)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+    TCGLabel *l = gen_new_label(tcg_ctx);
+    TCGv zero_local = tcg_temp_local_new(tcg_ctx);
+    TCGv r1_local = tcg_temp_local_new(tcg_ctx);
+    TCGv minusone_local = tcg_temp_local_new(tcg_ctx);
+
+    tcg_gen_movi_i32(tcg_ctx, zero_local, 0);
+    tcg_gen_movi_i32(tcg_ctx, minusone_local, 0xffffffff);
+    gen_get_gpr(tcg_ctx, r1_local, rs1);
+	gen_flags_on_add(tcg_ctx, r1_local, minusone_local);    //set flags
+	tcg_gen_add_i32(tcg_ctx, r1_local, r1_local, minusone_local);
+	gen_set_gpr(tcg_ctx, rs1, r1_local);
+
+	tcg_gen_brcond_tl(tcg_ctx, TCG_COND_NE, r1_local, zero_local, l);
+
+    tcg_temp_free(tcg_ctx, r1_local);
+    tcg_temp_free(tcg_ctx, zero_local);
+    tcg_temp_free(tcg_ctx, minusone_local);
+
+    gen_goto_tb_imm(ctx, 0, ctx->base.pc_next); 	// no jump, continue with next instr.
+    gen_set_label(tcg_ctx, l); 					// branch taken
+    gen_goto_tb_imm(ctx, 1, ctx->pc - disp16);
+
+    ctx->base.is_jmp = DISAS_TB_EXIT_ALREADY_GENERATED;
+}
+
+static void gen_bit_manipulation(DisasContext *ctx, int rs1, int rs2, int operation)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+	TCGv r1 = tcg_temp_new_i32(tcg_ctx);
+	TCGv r2 = tcg_temp_new_i32(tcg_ctx);
+	TCGv tcg_disp = tcg_temp_new_i32(tcg_ctx);
+	TCGv one = tcg_temp_new_i32(tcg_ctx);
+
+	TCGv temp = tcg_temp_new_i32(tcg_ctx);
+	TCGv test = tcg_temp_new_i32(tcg_ctx);
+	TCGv adr = tcg_temp_new_i32(tcg_ctx);
+	uint32_t disp16 = extract32(ctx->opcode, 16, 16);
+
+	int bit;
+
+	switch(operation){
+		case OPC_RH850_SET1_reg2_reg1:
+
+			gen_get_gpr(tcg_ctx, adr, rs1);
+			gen_get_gpr(tcg_ctx, r2, rs2);
+			tcg_gen_movi_i32(tcg_ctx, one, 0x1);
+
+			tcg_gen_qemu_ld_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+
+			tcg_gen_shl_i32(tcg_ctx, r2, one, r2);
+
+			tcg_gen_and_i32(tcg_ctx, test, temp, r2);
+			tcg_gen_setcond_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, test, r2);
+
+			tcg_gen_or_i32(tcg_ctx, temp, temp, r2);
+
+			tcg_gen_qemu_st_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+
+			break;
+		case OPC_RH850_SET1_bit3_disp16_reg1:
+
+			gen_get_gpr(tcg_ctx, r1, rs1);
+			tcg_gen_movi_i32(tcg_ctx, tcg_disp, disp16);
+			tcg_gen_ext16s_i32(tcg_ctx, tcg_disp, tcg_disp);
+			tcg_gen_add_i32(tcg_ctx, adr, r1, tcg_disp);
+
+			bit = extract32(ctx->opcode, 11, 3);
+
+			tcg_gen_qemu_ld_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+
+			tcg_gen_andi_i32(tcg_ctx, test, temp, (0x1 << bit));
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, test, (0x1 << bit));
+
+			tcg_gen_ori_i32(tcg_ctx, temp, temp, (0x1 << bit));
+
+			tcg_gen_qemu_st_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+			break;
+
+		case OPC_RH850_NOT1_reg2_reg1:
+
+			gen_get_gpr(tcg_ctx, adr, rs1);
+			gen_get_gpr(tcg_ctx, r2, rs2);
+			tcg_gen_movi_i32(tcg_ctx, one, 0x1);
+
+			tcg_gen_qemu_ld_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+
+			tcg_gen_shl_i32(tcg_ctx, r2, one, r2); // r2 = mask
+
+			tcg_gen_and_i32(tcg_ctx, test, temp, r2);
+			tcg_gen_setcond_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, test, r2);
+
+			//test = temp & mask
+			tcg_gen_and_i32(tcg_ctx, test, temp, r2);
+			//test = not (test) & mask
+			tcg_gen_not_i32(tcg_ctx, test, test);
+			tcg_gen_and_i32(tcg_ctx, test, test, r2);
+			//temp = temp & not(mask)
+			tcg_gen_not_i32(tcg_ctx, r2, r2);
+			tcg_gen_and_i32(tcg_ctx, temp, temp, r2);
+			//temp = temp or test
+			tcg_gen_or_i32(tcg_ctx, temp, temp, test);
+
+			tcg_gen_qemu_st_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+			break;
+
+		case OPC_RH850_NOT1_bit3_disp16_reg1:
+
+			gen_get_gpr(tcg_ctx, r1, rs1);
+			tcg_gen_movi_i32(tcg_ctx, tcg_disp, disp16);
+			tcg_gen_ext16s_i32(tcg_ctx, tcg_disp, tcg_disp);
+			tcg_gen_add_i32(tcg_ctx, adr, r1, tcg_disp);
+
+			bit = extract32(ctx->opcode, 11, 3);
+
+			tcg_gen_qemu_ld_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+
+			tcg_gen_andi_i32(tcg_ctx, test, temp, (0x1 << bit));
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, test, (0x1 << bit));
+
+			tcg_gen_movi_i32(tcg_ctx, r2, (0x1 << bit)); // r2 = mask
+
+			//test = temp & mask
+			tcg_gen_and_i32(tcg_ctx, test, temp, r2);
+			//test = not (test) & mask
+			tcg_gen_not_i32(tcg_ctx, test, test);
+			tcg_gen_and_i32(tcg_ctx, test, test, r2);
+			//temp = temp & not(mask)
+			tcg_gen_not_i32(tcg_ctx, r2, r2);
+			tcg_gen_and_i32(tcg_ctx, temp, temp, r2);
+			//temp = temp or test
+			tcg_gen_or_i32(tcg_ctx, temp, temp, test);
+
+			tcg_gen_qemu_st_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+			break;
+
+		case OPC_RH850_CLR1_reg2_reg1:
+
+			gen_get_gpr(tcg_ctx, adr, rs1);
+			gen_get_gpr(tcg_ctx, r2, rs2);
+			tcg_gen_movi_i32(tcg_ctx, one, 0x1);
+
+			tcg_gen_qemu_ld_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+			tcg_gen_andi_i32(tcg_ctx, r2, r2, 0x7);
+			tcg_gen_shl_i32(tcg_ctx, r2, one, r2);
+
+			tcg_gen_and_i32(tcg_ctx, test, temp, r2);
+			tcg_gen_setcond_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, test, r2);
+
+			tcg_gen_not_i32(tcg_ctx, r2, r2);
+			tcg_gen_and_i32(tcg_ctx, temp, temp, r2);
+
+			tcg_gen_qemu_st_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+			break;
+
+		case OPC_RH850_CLR1_bit3_disp16_reg1:
+
+			gen_get_gpr(tcg_ctx, r1, rs1);
+			tcg_gen_movi_i32(tcg_ctx, tcg_disp, disp16);
+			tcg_gen_ext16s_i32(tcg_ctx, tcg_disp, tcg_disp);
+			tcg_gen_add_i32(tcg_ctx, adr, r1, tcg_disp);
+
+			bit = extract32(ctx->opcode, 11, 3);
+
+			tcg_gen_qemu_ld_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+
+			tcg_gen_movi_i32(tcg_ctx, test, (0x1 << bit));
+			tcg_gen_andi_i32(tcg_ctx, test, temp, (0x1 << bit));
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, test, (0x1 << bit));
+
+			tcg_gen_movi_i32(tcg_ctx, test, (0x1 << bit));
+			tcg_gen_not_i32(tcg_ctx, test, test);
+			tcg_gen_and_i32(tcg_ctx, temp, temp, test);
+
+			tcg_gen_qemu_st_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+			break;
+
+		case OPC_RH850_TST1_reg2_reg1:
+
+			gen_get_gpr(tcg_ctx, adr, rs1);
+			gen_get_gpr(tcg_ctx, r2, rs2);
+			tcg_gen_movi_i32(tcg_ctx, one, 0x1);
+
+			tcg_gen_qemu_ld_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+
+			tcg_gen_shl_i32(tcg_ctx, r2, one, r2);
+
+			tcg_gen_and_i32(tcg_ctx, test, temp, r2);
+			tcg_gen_setcond_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, test, r2);
+			break;
+
+		case OPC_RH850_TST1_bit3_disp16_reg1:
+
+			gen_get_gpr(tcg_ctx, r1, rs1);
+			tcg_gen_movi_i32(tcg_ctx, tcg_disp, disp16);
+			tcg_gen_ext16s_i32(tcg_ctx, tcg_disp, tcg_disp);
+			tcg_gen_add_i32(tcg_ctx, adr, r1, tcg_disp);
+
+			bit = extract32(ctx->opcode, 11, 3);
+
+			tcg_gen_qemu_ld_i32(tcg_ctx, temp, adr, MEM_IDX, MO_UB);
+
+			tcg_gen_movi_i32(tcg_ctx, test, (0x1 << bit));
+			tcg_gen_andi_i32(tcg_ctx, test, temp, (0x1 << bit));
+			tcg_gen_setcondi_i32(tcg_ctx, TCG_COND_NE, cpu_ZF, test, (0x1 << bit));
+			break;
+	}
+
+	tcg_temp_free_i32(tcg_ctx, r1);
+	tcg_temp_free_i32(tcg_ctx, r2);
+	tcg_temp_free_i32(tcg_ctx, tcg_disp);
+	tcg_temp_free_i32(tcg_ctx, one);
+	tcg_temp_free_i32(tcg_ctx, temp);
+	tcg_temp_free_i32(tcg_ctx, test);
+	tcg_temp_free_i32(tcg_ctx, adr);
+
+}
+
+static void gen_update_ispr(DisasContext *ctx, CPURH850State *env)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+    TCGLabel *do_not_update = gen_new_label(tcg_ctx);
+    TCGLabel *clear_bit = gen_new_label(tcg_ctx);
+    TCGLabel *loop = gen_new_label(tcg_ctx);
+    TCGv temp = tcg_temp_local_new_i32(tcg_ctx);
+    TCGv idx = tcg_temp_local_new_i32(tcg_ctx);
+    TCGv ispr = tcg_temp_local_new_i32(tcg_ctx);
+
+    /* Move ISPR value into intcfg. */
+    tcg_gen_mov_i32(tcg_ctx, temp, cpu_sysRegs[BANK_ID_BASIC_2][INTCFG_IDX2]);
+
+    /* And intcfg with 1. */
+    tcg_gen_andi_i32(tcg_ctx, temp, temp, 1);
+
+    /* Compare intcfg, jump to do_not_process if 1. */
+    tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, temp, 0, do_not_update);
+
+    /* INTCFG.ICSP = 0, now check EP (EP == 1 -> do not update ISRP) */
+    tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, cpu_EP, 0, do_not_update);
+
+    /**
+     * Okay, now update ISPR (clear the highest priority bit).
+     * We need to loop from bit 0 to bit 15, clear bit and exit loop if bit is
+     * set.
+     **/
+
+    /* Set mask to 1. */
+    tcg_gen_movi_i32(tcg_ctx, temp, 1);
+    tcg_gen_movi_i32(tcg_ctx, idx, 0);
+
+    gen_set_label(tcg_ctx, loop);
+
+    /* Load ISPR. */
+    tcg_gen_mov_i32(tcg_ctx, ispr, cpu_sysRegs[BANK_ID_BASIC_2][ISPR_IDX2]);
+    tcg_gen_and_i32(tcg_ctx, ispr, ispr, temp);
+    tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, ispr, 1, clear_bit);
+
+    /* shift left our mask, exit if done. */
+    tcg_gen_shli_i32(tcg_ctx, temp, temp, 1);
+    tcg_gen_addi_i32(tcg_ctx, idx, idx, 1);
+
+    tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_LT, idx, 2, loop);
+
+    tcg_gen_br(tcg_ctx, do_not_update);
+
+    /* Clear bit. */
+    gen_set_label(tcg_ctx, clear_bit);
+    tcg_gen_xor_i32(tcg_ctx, cpu_sysRegs[BANK_ID_BASIC_2][ISPR_IDX2], cpu_sysRegs[BANK_ID_BASIC_2][ISPR_IDX2], temp);
+
+    /* Set label do_not_update here. */
+    gen_set_label(tcg_ctx, do_not_update);
+
+    /* Free resources. */
+    tcg_temp_free_i32(tcg_ctx, temp);
+    tcg_temp_free_i32(tcg_ctx, ispr);
+}
+
+static void gen_special(DisasContext *ctx, CPURH850State *env, int rs1, int rs2, int operation)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+	TCGLabel *storeReg3;
+	TCGLabel *cont;
+	int regID;
+	int selID = 0;
+	int imm;
+    int vector;
+
+	switch(operation){
+	case OPC_RH850_CALLT_imm6: {
+        TCGv temp = tcg_temp_new_i32(tcg_ctx);
+        TCGv adr = tcg_temp_new_i32(tcg_ctx);
+
+		//setting CTPC to PC+2
+		tcg_gen_addi_i32(tcg_ctx, cpu_sysRegs[BANK_ID_BASIC_0][CTPC_IDX], cpu_pc, 0x2);
+		//setting CPTSW bits 0:4
+		flags_to_tcgv_z_cy_ov_s_sat(tcg_ctx, cpu_sysRegs[BANK_ID_BASIC_0][CTPSW_IDX]);
+
+		imm = extract32(ctx->opcode, 0, 6);
+		tcg_gen_movi_i32(tcg_ctx, adr, imm);
+		tcg_gen_shli_i32(tcg_ctx, adr, adr, 0x1);
+		tcg_gen_ext8s_i32(tcg_ctx, adr, adr);
+		tcg_gen_add_i32(tcg_ctx, adr, cpu_sysRegs[BANK_ID_BASIC_0][CTBP_IDX], adr);
+
+		tcg_gen_qemu_ld16u(tcg_ctx, temp, adr, 0);
+
+		tcg_gen_add_i32(tcg_ctx, cpu_pc, temp, cpu_sysRegs[BANK_ID_BASIC_0][CTBP_IDX]);
+	    ctx->base.is_jmp = DISAS_EXIT_TB;
+
+	    tcg_temp_free(tcg_ctx, temp);
+	    tcg_temp_free(tcg_ctx, adr);
+	} break;
+
+	case OPC_RH850_CAXI_reg1_reg2_reg3: {
+	    TCGv temp = tcg_temp_new_i32(tcg_ctx);
+	    TCGv adr = tcg_temp_new_i32(tcg_ctx);
+	    TCGv r2 = tcg_temp_new(tcg_ctx);
+	    TCGv r3 = tcg_temp_new(tcg_ctx);
+
+		storeReg3 = gen_new_label(tcg_ctx);
+		gen_get_gpr(tcg_ctx, adr, rs1);
+		gen_get_gpr(tcg_ctx, r2, rs2);
+		int rs3 = extract32(ctx->opcode, 27, 5);
+		gen_get_gpr(tcg_ctx, r3, rs3);
+		tcg_gen_qemu_ld32u(tcg_ctx, temp, adr, 0);
+		storeReg3 = gen_new_label(tcg_ctx);
+		cont = gen_new_label(tcg_ctx);
+
+		TCGv local_adr = tcg_temp_local_new_i32(tcg_ctx);
+		TCGv local_r2 = tcg_temp_local_new_i32(tcg_ctx);
+		TCGv local_r3 = tcg_temp_local_new_i32(tcg_ctx);
+		TCGv local_temp = tcg_temp_local_new_i32(tcg_ctx);
+
+		tcg_gen_mov_i32(tcg_ctx, local_adr, adr);
+		tcg_gen_mov_i32(tcg_ctx, local_r2, r2);
+		tcg_gen_mov_i32(tcg_ctx, local_r3, r3);
+		tcg_gen_mov_i32(tcg_ctx, local_temp, temp);
+
+		gen_flags_on_sub(tcg_ctx, local_r2, local_temp);
+
+		tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, cpu_ZF, 0x1, storeReg3);
+		tcg_gen_qemu_st_tl(tcg_ctx, local_temp, local_adr, MEM_IDX, MO_TESL);
+		tcg_gen_br(tcg_ctx, cont);
+
+		gen_set_label(tcg_ctx, storeReg3);
+		tcg_gen_qemu_st_tl(tcg_ctx, local_r3, local_adr, MEM_IDX, MO_TESL);
+
+		gen_set_label(tcg_ctx, cont);
+		gen_set_gpr(tcg_ctx, rs3, local_temp);
+
+        tcg_temp_free(tcg_ctx, temp);
+        tcg_temp_free(tcg_ctx, adr);
+        tcg_temp_free(tcg_ctx, r2);
+        tcg_temp_free(tcg_ctx, r3);
+		break;
+	}
+
+	case OPC_RH850_CTRET: {
+	    TCGv temp = tcg_temp_new_i32(tcg_ctx);
+
+		tcg_gen_mov_i32(tcg_ctx, cpu_pc, cpu_sysRegs[BANK_ID_BASIC_0][CTPC_IDX]);
+		tcgv_to_flags_z_cy_ov_s_sat(tcg_ctx, cpu_sysRegs[BANK_ID_BASIC_0][CTPSW_IDX]);
+
+	    ctx->base.is_jmp = DISAS_EXIT_TB;
+
+	    tcg_temp_free(tcg_ctx, temp);
+	} break;
+
+	case OPC_RH850_DI:
+		tcg_gen_movi_i32(tcg_ctx, cpu_ID, 0x1);
+		break;
+
+	case OPC_RH850_DISPOSE_imm5_list12: {
+	    TCGv temp = tcg_temp_new_i32(tcg_ctx);
+	    TCGv adr = tcg_temp_new_i32(tcg_ctx);
+
+		int list [12] = {31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20};
+		int numOfListItems = sizeof(list) / sizeof(list[0]);
+		int list12 = extract32(ctx->opcode, 0, 1) | ( (extract32(ctx->opcode, 21, 11)) << 1);
+
+		// reorganising bits that indicate the registers to load
+		// doing this for easier looping in correct order
+		int dispList = 	((list12 & 0x80) << 4) |
+						((list12 & 0x40) << 4) |
+						((list12 & 0x20) << 4) |
+						((list12 & 0x10) << 4) |
+						((list12 & 0x800) >> 4) |
+						((list12 & 0x400) >> 4) |
+						((list12 & 0x200) >> 4) |
+						((list12 & 0x100) >> 4) |
+						((list12 & 0x8) << 0) |
+						((list12 & 0x4) << 0) |
+						((list12 & 0x2) >> 1) |
+						((list12 & 0x1) << 1) ;
+
+		int test = 0x1;
+		gen_get_gpr(tcg_ctx, temp, 3); // stack pointer (sp) register is cpu_gpr[3]
+		tcg_gen_addi_i32(tcg_ctx, temp, temp, (extract32(ctx->opcode, 1, 5) << 2));
+
+		TCGv regToLoad = tcg_temp_new_i32(tcg_ctx);
+
+		for(int i=0; i<numOfListItems; i++){
+			tcg_gen_andi_i32(tcg_ctx, adr, temp, 0xfffffffc); //masking the lower two bits
+
+			if( !((dispList & test)==0x0) ){
+				tcg_gen_qemu_ld_i32(tcg_ctx, regToLoad, adr, MEM_IDX, MO_TESL);
+
+				gen_set_gpr(tcg_ctx, list[i], regToLoad);
+				tcg_gen_addi_i32(tcg_ctx, temp, temp, 0x4);
+			}
+			test = test << 1;
+		}
+		gen_set_gpr(tcg_ctx, 3, temp);
+
+		tcg_temp_free(tcg_ctx, temp);
+        tcg_temp_free(tcg_ctx, adr);
+		}
+
+		break;
+
+	case OPC_RH850_DISPOSE_imm5_list12_reg1: {
+	    TCGv temp = tcg_temp_new_i32(tcg_ctx);
+	    TCGv adr = tcg_temp_new_i32(tcg_ctx);
+
+		int list [12] = {31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20};
+		int numOfListItems = sizeof(list) / sizeof(list[0]);
+		int list12 = extract32(ctx->opcode, 0, 1) | ( (extract32(ctx->opcode, 21, 11)) << 1);
+		TCGv jmpAddr = tcg_temp_new_i32(tcg_ctx);
+
+		// reorganising bits that indicate the registers to load
+		// doing this for easier looping in correct order
+		int dispList = 	((list12 & 0x80) << 4) |
+						((list12 & 0x40) << 4) |
+						((list12 & 0x20) << 4) |
+						((list12 & 0x10) << 4) |
+						((list12 & 0x800) >> 4) |
+						((list12 & 0x400) >> 4) |
+						((list12 & 0x200) >> 4) |
+						((list12 & 0x100) >> 4) |
+						((list12 & 0x8) << 0) |
+						((list12 & 0x4) << 0) |
+						((list12 & 0x2) >> 1) |
+						((list12 & 0x1) << 1) ;
+
+		int test = 0x1;
+		gen_get_gpr(tcg_ctx, temp, 3); // stack pointer (sp) register is cpu_gpr[3]
+		tcg_gen_addi_i32(tcg_ctx, temp, temp, (extract32(ctx->opcode, 1, 5) << 2));
+
+		TCGv regToLoad = tcg_temp_new_i32(tcg_ctx);
+
+		for(int i=0; i<numOfListItems; i++){
+			tcg_gen_andi_i32(tcg_ctx, adr, temp, 0xfffffffc); //masking the lower two bits
+
+			if( !((dispList & test)==0x0) ){
+				tcg_gen_qemu_ld_i32(tcg_ctx, regToLoad, adr, MEM_IDX, MO_TESL);
+
+				gen_set_gpr(tcg_ctx, list[i], regToLoad);
+				tcg_gen_addi_i32(tcg_ctx, temp, temp, 0x4);
+			}
+			test = test << 1;
+		}
+
+		gen_get_gpr(tcg_ctx, jmpAddr, (extract32(ctx->opcode, 16, 5)));
+		tcg_gen_mov_i32(tcg_ctx, cpu_pc, jmpAddr);
+
+		gen_set_gpr(tcg_ctx, 3, temp);
+	    ctx->base.is_jmp = DISAS_EXIT_TB;
+
+	    tcg_temp_free(tcg_ctx, temp);
+        tcg_temp_free(tcg_ctx, adr);
+		}
+	    break;
+
+	case OPC_RH850_EI:
+		tcg_gen_movi_i32(tcg_ctx, cpu_ID, 0x0);
+		break;
+	case OPC_RH850_EIRET:
+        /* Move EIPC to PC and EIPSW to PSW. */
+        tcg_gen_mov_i32(tcg_ctx, cpu_pc, cpu_sysRegs[BANK_ID_BASIC_0][EIPC_IDX]);
+        tcgv_to_flags(tcg_ctx, cpu_sysRegs[BANK_ID_BASIC_0][EIPSW_IDX]);
+
+        /* Update ISPR. */
+        gen_update_ispr(ctx, env);
+        ctx->base.is_jmp = DISAS_EXIT_TB;
+		break;
+	case OPC_RH850_FERET:
+		tcg_gen_mov_i32(tcg_ctx, cpu_pc, cpu_sysRegs[BANK_ID_BASIC_0][FEPC_IDX]);
+        tcgv_to_flags(tcg_ctx, cpu_sysRegs[BANK_ID_BASIC_0][FEPSW_IDX]);
+	    ctx->base.is_jmp = DISAS_EXIT_TB;
+		break;
+
+	case OPC_RH850_FETRAP_vector4: {
+
+		vector = extract32(ctx->opcode, 11, 4);
+        TCGv_i32 excp = tcg_const_i32(tcg_ctx, RH850_EXCP_FETRAP);
+        TCGv_i32 cause = tcg_const_i32(tcg_ctx, vector + 0x30);
+        gen_helper_raise_exception_with_cause(tcg_ctx, tcg_ctx->cpu_env, excp, cause);
+        tcg_temp_free_i32(tcg_ctx, excp);
+        tcg_temp_free_i32(tcg_ctx, cause);
+        ctx->base.is_jmp = DISAS_NORETURN;
+	}	break;
+
+	case OPC_RH850_HALT:
+	    // nop, interupts are not implemented, so HALT would never continue
+	    // tcg_abort();
+		break;
+
+    case OPC_RH850_LDSR_reg2_regID_selID:
+        selID = extract32(ctx->opcode, 27, 5);
+        regID = rs2;
+
+        // Modify only sytem regs, which exist. Real device executes instruction, but
+        // value is not stored for system regs, which do not exist. No exception is
+        // thrown.
+        if(cpu_sysRegs[selID][regID] != NULL  ||  (selID == BANK_ID_BASIC_0  &&  regID == PSW_IDX)) {
+
+            TCGv tmp = tcg_temp_new(tcg_ctx);
+            gen_get_gpr(tcg_ctx, tmp, rs1);
+
+            if(selID == BANK_ID_BASIC_0  &&  regID == PSW_IDX){
+                tcgv_to_flags(tcg_ctx, tmp);
+            } else {
+                // clear read-only bits in value, all other bits in sys reg. This way
+                // read-only bits preserve their value given at reset
+                tcg_gen_andi_i32(tcg_ctx, tmp, tmp, rh850_sys_reg_read_only_masks[selID][regID]);
+                tcg_gen_andi_i32(tcg_ctx, cpu_sysRegs[selID][regID], cpu_sysRegs[selID][regID], ~rh850_sys_reg_read_only_masks[selID][regID]);
+                tcg_gen_or_i32(tcg_ctx, cpu_sysRegs[selID][regID], cpu_sysRegs[selID][regID], tmp);
+            }
+            tcg_temp_free(tcg_ctx, tmp);
+        }
+		break;
+
+	//case OPC_RH850_LDLW:
+		//break;
+
+	//case OPC_RH850_NOP:
+		//break;
+
+	case OPC_RH850_POPSP_rh_rt:  {
+	    TCGv temp = tcg_temp_new_i32(tcg_ctx);
+	    TCGv adr = tcg_temp_new_i32(tcg_ctx);
+
+		uint32_t rs3 = extract32(ctx->opcode, 27, 5);
+
+		int numOfRegs = (rs3-rs1)+1;
+
+		gen_get_gpr(tcg_ctx, temp, 3); // stack pointer register is cpu_gpr[3]
+		TCGv regToLoad = tcg_temp_new_i32(tcg_ctx);
+
+		if(rs1<=rs3){
+
+			for(int i=0; i<numOfRegs; i++){
+
+				tcg_gen_andi_i32(tcg_ctx, adr, temp, 0xfffffffc); // masking the lower two bits
+
+				tcg_gen_qemu_ld_i32(tcg_ctx, regToLoad, adr, MEM_IDX, MO_TESL);
+
+				gen_set_gpr(tcg_ctx, rs3-i, regToLoad);
+				tcg_gen_addi_i32(tcg_ctx, temp, temp, 0x4);
+
+				}
+			gen_set_gpr(tcg_ctx, 3, temp);
+		}
+
+        tcg_temp_free(tcg_ctx, temp);
+        tcg_temp_free(tcg_ctx, adr);
+	}	break;
+
+	case OPC_RH850_PREPARE_list12_imm5:{
+	    TCGv temp = tcg_temp_new_i32(tcg_ctx);
+	    TCGv adr = tcg_temp_new_i32(tcg_ctx);
+
+		// how to manually affect the ff field?
+
+		int list [12] = {20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
+		int list12 = ( (extract32(ctx->opcode, 21, 11) << 1) | (extract32(ctx->opcode, 0, 1) ) ) ;
+		int numOfListItems = sizeof(list) / sizeof(list[0]);
+		int prepList = 	((list12 & 0x80) >> 7) |
+						((list12 & 0x40) >> 5) |
+						((list12 & 0x20) >> 3) |
+						((list12 & 0x10) >> 1) |
+						((list12 & 0x800) >> 7) |
+						((list12 & 0x400) >> 5) |
+						((list12 & 0x200) >> 3) |
+						((list12 & 0x100) >> 1) |
+						((list12 & 0x8) << 5) |
+						((list12 & 0x4) << 7) |
+						((list12 & 0x2) << 10) |
+						((list12 & 0x1) << 10) ;
+
+		int test = 0x1;
+		gen_get_gpr(tcg_ctx, temp, 3); // stack pointer register is cpu_gpr[3]
+		TCGv regToStore = tcg_temp_new_i32(tcg_ctx);
+
+		for(int i=0; i<numOfListItems; i++){
+
+			if( !((prepList & test)==0x0) ){
+				tcg_gen_subi_i32(tcg_ctx, temp, temp, 0x4);
+				tcg_gen_andi_i32(tcg_ctx, adr, temp, 0xfffffffc); //masking the lower two bits
+				gen_get_gpr(tcg_ctx, regToStore, list[i]);
+				tcg_gen_qemu_st_i32(tcg_ctx, regToStore, adr, MEM_IDX, MO_TESL);
+				gen_set_gpr(tcg_ctx, list[i], regToStore);
+			}
+			test = test << 1;
+		}
+		tcg_gen_subi_i32(tcg_ctx, temp, temp, (extract32(ctx->opcode, 1, 5) << 2));
+		gen_set_gpr(tcg_ctx, 3, temp);
+
+        tcg_temp_free(tcg_ctx, temp);
+        tcg_temp_free(tcg_ctx, adr);
+	}	break;
+
+	case OPC_RH850_PREPARE_list12_imm5_sp:{
+	    TCGv temp = tcg_temp_new_i32(tcg_ctx);
+	    TCGv adr = tcg_temp_new_i32(tcg_ctx);
+
+		int list [12] = {20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
+		uint32_t list12 = extract32(ctx->opcode, 0, 1) | ( (extract32(ctx->opcode, 21, 11)) << 1);
+		int numOfListItems = sizeof(list) / sizeof(list[0]);
+		int prepList = 	((list12 & 0x80) >> 7) |
+								((list12 & 0x40) >> 5) |
+								((list12 & 0x20) >> 3) |
+								((list12 & 0x10) >> 1) |
+								((list12 & 0x800) >> 7) |
+								((list12 & 0x400) >> 5) |
+								((list12 & 0x200) >> 3) |
+								((list12 & 0x100) >> 1) |
+								((list12 & 0x8) << 5) |
+								((list12 & 0x4) << 7) |
+								((list12 & 0x2) << 10) |
+								((list12 & 0x1) << 10) ;
+
+		uint32_t imm = 0x0;
+
+		int test = 0x1;
+		int ff = extract32(ctx->opcode, 19, 2);
+		gen_get_gpr(tcg_ctx, temp, 3); // stack pointer register is cpu_gpr[3]
+		TCGv regToStore = tcg_temp_new_i32(tcg_ctx);
+
+		for(int i=0; i<numOfListItems; i++){
+
+			if( !((prepList & test)==0x0) ){
+				tcg_gen_subi_i32(tcg_ctx, temp, temp, 0x4);
+				tcg_gen_andi_i32(tcg_ctx, adr, temp, 0xfffffffc); //masking the lower two bits
+				gen_get_gpr(tcg_ctx, regToStore, list[i]);
+				tcg_gen_qemu_st32(tcg_ctx, regToStore, adr, MEM_IDX);
+				gen_set_gpr(tcg_ctx, list[i], regToStore);
+			}
+			test = test << 1;
+		}
+
+		tcg_gen_subi_i32(tcg_ctx, temp, temp, (extract32(ctx->opcode, 1, 5) << 2));
+
+		gen_set_gpr(tcg_ctx, 3, temp);
+
+		switch(ff){
+
+			case 0x0:
+				gen_set_gpr(tcg_ctx, 30, temp); //moving sp to ep (element pointer is at cpu_gpr[30])
+				break;
+
+			case 0x1:
+				imm = cpu_lduw_code(env, ctx->base.pc_next); // fetching additional 16bits from memory
+				tcg_gen_movi_i32(tcg_ctx, temp, imm);
+				tcg_gen_ext16s_i32(tcg_ctx, temp, temp);
+				gen_set_gpr(tcg_ctx, 30, temp);
+				ctx->base.pc_next+=2;						// increasing PC due to additional fetch
+				break;
+
+			case 0x2:
+				imm = cpu_lduw_code(env, ctx->base.pc_next); // fetching additional 16bits from memory
+				tcg_gen_movi_i32(tcg_ctx, temp, imm);
+				tcg_gen_shli_i32(tcg_ctx, temp, temp, 0x10);
+				gen_set_gpr(tcg_ctx, 30, temp);
+				ctx->base.pc_next+=2;
+				break;
+
+			case 0x3:
+				imm = cpu_lduw_code(env, ctx->base.pc_next) |
+				(cpu_lduw_code(env, ctx->base.pc_next + 2) << 0x10);
+				// fetching additional 32bits from memory
+
+				tcg_gen_movi_i32(tcg_ctx, temp, imm);
+				gen_set_gpr(tcg_ctx, 30, temp);
+				ctx->base.pc_next = ctx->base.pc_next + 4;
+				break;
+		}
+
+        tcg_temp_free(tcg_ctx, temp);
+        tcg_temp_free(tcg_ctx, adr);
+		}	break;
+
+	case OPC_RH850_PUSHSP_rh_rt: {
+	    TCGv temp = tcg_temp_new_i32(tcg_ctx);
+	    TCGv adr = tcg_temp_new_i32(tcg_ctx);
+
+		uint32_t rs3 = extract32(ctx->opcode, 27, 5);
+
+		int numOfRegs = (rs3-rs1)+1;
+
+		gen_get_gpr(tcg_ctx, temp, 3); // stack pointer register is cpu_gpr[3]
+		TCGv regToStore = tcg_temp_new_i32(tcg_ctx);
+		if(rs1<=rs3){
+
+			for(int i=0; i<numOfRegs; i++){
+				tcg_gen_subi_i32(tcg_ctx, temp, temp, 0x4);
+				tcg_gen_andi_i32(tcg_ctx, adr, temp, 0xfffffffc); // masking the lower two bits
+
+				gen_get_gpr(tcg_ctx, regToStore, rs1+i);
+
+				tcg_gen_qemu_st_i32(tcg_ctx, regToStore, adr, MEM_IDX, MO_TESL);
+				}
+			gen_set_gpr(tcg_ctx, 3, temp);
+		}
+
+        tcg_temp_free(tcg_ctx, temp);
+        tcg_temp_free(tcg_ctx, adr);
+	}	break;
+
+	case OPC_RH850_RIE: {
+
+		TCGv_i32 excp = tcg_const_i32(tcg_ctx, RH850_EXCP_RIE);
+        TCGv_i32 cause = tcg_const_i32(tcg_ctx, 0x60);
+        gen_helper_raise_exception_with_cause(tcg_ctx, tcg_ctx->cpu_env, excp, cause);
+        tcg_temp_free_i32(tcg_ctx, excp);
+        tcg_temp_free_i32(tcg_ctx, cause);
+        ctx->base.is_jmp = DISAS_NORETURN;
+
+	}	break;
+
+	case OPC_RH850_SNOOZE:
+		break;
+
+	//case OPC_RH850_STCW:
+	//	break;
+
+	case OPC_RH850_STSR_regID_reg2_selID:
+		regID=rs1;
+		selID = extract32(ctx->opcode, 27, 5);
+        if(selID == BANK_ID_BASIC_0  &&  regID == PSW_IDX){
+            TCGv tmp = tcg_temp_new_i32(tcg_ctx);
+            tcg_gen_movi_tl(tcg_ctx, tmp, 0);
+            flags_to_tcgv(tcg_ctx, tmp);
+            gen_set_gpr(tcg_ctx, rs2, tmp);
+            tcg_temp_free(tcg_ctx, tmp);
+        } else {
+            if (cpu_sysRegs[selID][regID] != NULL) {
+                gen_set_gpr(tcg_ctx, rs2, cpu_sysRegs[selID][regID]);
+            } else {
+                TCGv dat = tcg_temp_local_new(tcg_ctx);
+                tcg_gen_movi_i32(tcg_ctx, dat, 0);
+                gen_set_gpr(tcg_ctx, rs2, 0); // if sys reg does not exist, write 0
+                tcg_temp_free(tcg_ctx, dat);
+            }
+        }
+		break;
+
+	case OPC_RH850_SWITCH_reg1: {
+	    TCGv temp = tcg_temp_new_i32(tcg_ctx);
+	    TCGv adr = tcg_temp_new_i32(tcg_ctx);
+
+		gen_get_gpr(tcg_ctx, adr, rs1);
+		tcg_gen_shli_i32(tcg_ctx, adr, adr, 0x1);
+		tcg_gen_add_i32(tcg_ctx, adr, adr, cpu_pc);
+		tcg_gen_addi_i32(tcg_ctx, adr, adr, 0x2);
+
+		tcg_gen_addi_i32(tcg_ctx, cpu_pc, cpu_pc, 0x2);
+		tcg_gen_qemu_ld16s(tcg_ctx, temp, adr, MEM_IDX);
+		tcg_gen_ext16s_i32(tcg_ctx, temp, temp);
+		tcg_gen_shli_i32(tcg_ctx, temp, temp, 0x1);
+		tcg_gen_add_i32(tcg_ctx, cpu_pc, cpu_pc, temp);
+	    ctx->base.is_jmp = DISAS_EXIT_TB;
+	} break;
+
+	// SYNC instructions will not be implemented
+	case OPC_RH850_SYNCE:
+	case OPC_RH850_SYNCI:
+	case OPC_RH850_SYNCM:
+	case OPC_RH850_SYNCP:
+		break;
+
+	case OPC_RH850_TRAP:
+        {
+            int vector5 = rs1;
+            TCGv_i32 excp = tcg_const_i32(tcg_ctx, RH850_EXCP_TRAP);
+            TCGv_i32 cause = tcg_const_i32(tcg_ctx, vector5 + 0x40);
+            gen_helper_raise_exception_with_cause(tcg_ctx, tcg_ctx->cpu_env, excp, cause);
+            tcg_temp_free_i32(tcg_ctx, excp);
+            tcg_temp_free_i32(tcg_ctx, cause);
+            ctx->base.is_jmp = DISAS_NORETURN;
+        }
+        break;
+
+	case OPC_RH850_SYSCALL:
+		{
+            int vector = extract32(ctx->opcode, 0, 5) | ((extract32(ctx->opcode, 27, 3)) << 5);
+            // int vector=5;
+            TCGv_i32 excp = tcg_const_i32(tcg_ctx, RH850_EXCP_SYSCALL);
+            TCGv_i32 cause = tcg_const_i32(tcg_ctx, vector + 0x8000);
+            gen_helper_raise_exception_with_cause(tcg_ctx, tcg_ctx->cpu_env, excp, cause);
+            tcg_temp_free_i32(tcg_ctx, excp);
+            tcg_temp_free_i32(tcg_ctx, cause);
+            ctx->base.is_jmp = DISAS_NORETURN;
+        }
+        break;
+	}
+}
+
+/* Cache operations are not supported on single core emulation. */
+static void gen_cache(DisasContext *ctx, int rs1, int rs2, int operation){
+	int cache_op = (extract32(ctx->opcode,11, 2) << 5 ) | (extract32(ctx->opcode, 27, 5));
+	switch(cache_op){
+		case CHBII:
+			// printf("CHBII\n");
+			break;
+		case CIBII:
+			// printf("CIBII\n");
+			break;
+		case CFALI:
+			// printf("CFALI\n");
+			break;
+		case CISTI:
+			// printf("CISTI\n");
+			break;
+		case CILDI:
+			// printf("CILDI\n");
+			break;
+		case CLL:
+			// printf("CLL\n");
+		    // this operation is not implemented on single core
+			break;
+	}
+}
+
+/* 48-bit RH850 instruction decoding */
+static void decode_RH850_48(CPURH850State *env, DisasContext *ctx)
+{
+	int rs1, rs3;
+	uint64_t opcode48;
+
+	rs1 = GET_RS1(ctx->opcode);
+	rs3 = extract32(ctx->opcode, 27, 5);
+
+	opcode48 = (ctx->opcode1);
+	opcode48 = (ctx->opcode) | (opcode48  << 0x20);
+	uint32_t opcode20 = extract32(opcode48,0,20) & 0xfffe0;
+
+	uint32_t disp23 = (ctx->opcode1 << 7) | (extract32(ctx->opcode, 21, 6) << 1);
+	uint32_t disp32 = (opcode48 >> 16);
+
+	switch(opcode20) {
+
+
+		case OPC_RH850_LDB2:
+	        gen_load(ctx, MO_SB, rs3, rs1, disp23, 1);
+			break;
+		case OPC_RH850_LDH2:
+	        gen_load(ctx, MO_TESW, rs3, rs1, disp23, 1);
+			break;
+		case OPC_RH850_LDW2:
+	        gen_load(ctx, MO_TESL, rs3, rs1, disp23, 1);
+			break;
+		case OPC_RH850_LDDW:
+	        gen_load(ctx, MO_TEQ, rs3, rs1, disp23, 1);
+			break;
+		case OPC_RH850_LDBU2:
+	        gen_load(ctx, MO_UB, rs3, rs1, disp23, 1);
+			break;
+		case OPC_RH850_LDHU2:
+	        gen_load(ctx, MO_TEUW, rs3, rs1, disp23, 1);
+			break;
+
+		case OPC_RH850_STB2:
+	        gen_store(ctx, MO_SB, rs1, rs3, disp23, 1);
+			break;
+		case OPC_RH850_STH2:
+	        gen_store(ctx, MO_TESW, rs1, rs3, disp23, 1);
+			break;
+		case OPC_RH850_STW2:
+	        gen_store(ctx, MO_TESL, rs1, rs3, disp23, 1);
+			break;
+		case OPC_RH850_STDW:
+	    	gen_store(ctx, MO_TEQ, rs1, rs3, disp23, 1);
+			break;
+	}
+
+	if (extract32(ctx->opcode, 5, 11) == 0x31) {
+		gen_arithmetic(ctx, 0, rs1, OPC_RH850_MOV_imm32_reg1);
+	} else if (extract32(ctx->opcode, 5, 12) == 0x37) {
+		gen_jmp(ctx, rs1, disp32, OPC_RH850_JMP_disp32_reg1);
+	} else if (extract32(ctx->opcode, 5, 11) == 0x17) {
+		if (rs1 == 0x0){
+			gen_jmp(ctx, 0, disp32, OPC_RH850_JR_imm32);
+
+		} else {
+			gen_jmp(ctx, rs1, disp32, OPC_RH850_JARL_disp32_reg1);
+		}
+	}
+}
+
+/* 32-bit RH850 instruction decoding */
+static void decode_RH850_32(CPURH850State *env, DisasContext *ctx)
+{
+    TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
+
+	int rs1;
+	int rs2;
+	int cond;
+	uint32_t op;
+	uint32_t formXop;
+	uint32_t checkXII;
+	uint32_t check32bitZERO;
+	target_long imm_32;
+	target_long ld_imm;
+
+	op = MASK_OP_MAJOR(ctx->opcode);
+	rs1 = GET_RS1(ctx->opcode);			// rs1 is at b0-b4;
+	rs2 = GET_RS2(ctx->opcode);			// rs2 is at b11-b15;
+	TCGv r1 = tcg_temp_local_new(tcg_ctx);
+	TCGv r2 = tcg_temp_local_new(tcg_ctx);
+	imm_32 = GET_IMM_32(ctx->opcode);
+	ld_imm = extract32(ctx->opcode, 16, 16);
+
+	gen_get_gpr(tcg_ctx, r1, rs1);
+	gen_get_gpr(tcg_ctx, r2, rs2);
+
+	switch(op){
+
+		case OPC_RH850_LDB:
+	        gen_load(ctx, MO_SB, rs2, rs1, ld_imm, 0);
+	    	break;
+
+	    case OPC_RH850_LDH_LDW:
+	    	if ( extract32(ctx->opcode, 16, 1) == 0 ){
+	    		gen_load(ctx, MO_TESW, rs2, rs1, ld_imm, 0);	// LD.H
+	    	}
+	    	else{
+	    		gen_load(ctx, MO_TESL, rs2, rs1, ld_imm & 0xfffe, 0);	// LD.W
+	    	}
+	    	break;
+
+	    case OPC_RH850_STB:
+	    	gen_store(ctx, MO_SB, rs1, rs2, (extract32(ctx->opcode, 16, 16)), 0);
+	    	break;
+
+	    case OPC_RH850_STH_STW:
+	    	if ( extract32(ctx->opcode, 16, 1)==1 ) {
+	    		gen_store(ctx, MO_TESL, rs1, rs2, ((extract32(ctx->opcode, 17, 15))) << 1, 0);
+	    		//this is STORE WORD
+	    		break;
+	    	}
+	    	gen_store(ctx, MO_TESW, rs1, rs2, ((extract32(ctx->opcode, 17, 15))) << 1, 0);
+	    	//this is STORE HALFWORD
+	    	break;
+
+	    case OPC_RH850_ADDI_imm16_reg1_reg2:
+	    	gen_arithmetic(ctx, rs1,rs2, OPC_RH850_ADDI_imm16_reg1_reg2);
+	    	break;
+
+	    case OPC_RH850_ANDI_imm16_reg1_reg2:
+	    	gen_logical(ctx, rs1, rs2, OPC_RH850_ANDI_imm16_reg1_reg2);
+	    	break;
+
+	    case OPC_RH850_MOVEA:
+	    	if ( extract32(ctx->opcode, 11, 5) == 0 ){
+	    		// This is 48bit MOV
+	    		// This instruction should be reached first in decode_RH850_48
+	    	} else {
+	    		gen_arithmetic(ctx, rs1, rs2, OPC_RH850_MOVEA_imm16_reg1_reg2);
+	    	}
+	    	break;
+
+	    case OPC_RH850_MOVHI_imm16_reg1_reg2:
+	    	if(extract32(ctx->opcode, 11, 5)!=0x0){
+	    		gen_arithmetic(ctx, rs1, rs2, OPC_RH850_MOVHI_imm16_reg1_reg2);
+	    	} else {
+	    		if(extract32(ctx->opcode, 16, 5)==0x0){
+	    			gen_special(ctx, env, rs1, rs2, OPC_RH850_DISPOSE_imm5_list12);
+	    		} else {
+	    			gen_special(ctx, env, rs1, rs2, OPC_RH850_DISPOSE_imm5_list12_reg1);
+	    		}
+	    	}
+	    	break;
+
+	    case OPC_RH850_ORI_imm16_reg1_reg2:
+	    	gen_logical(ctx, rs1, rs2, OPC_RH850_ORI_imm16_reg1_reg2);
+	    	break;
+
+	    case OPC_RH850_SATSUBI_imm16_reg1_reg2:
+	    	if(extract32(ctx->opcode, 11, 5)!=0x0){
+	    		gen_sat_op(ctx, rs1, rs2, OPC_RH850_SATSUBI_imm16_reg1_reg2);
+			} else {
+				if(extract32(ctx->opcode, 16, 5)==0x0){
+					gen_special(ctx, env, rs1, rs2, OPC_RH850_DISPOSE_imm5_list12);
+				} else {
+					gen_special(ctx, env, rs1, rs2, OPC_RH850_DISPOSE_imm5_list12_reg1);
+				}
+			}
+
+	    	break;
+	    case OPC_RH850_XORI_imm16_reg1_reg2:
+	    	gen_logical(ctx, rs1, rs2, OPC_RH850_XORI_imm16_reg1_reg2);
+	    	break;
+
+	    case OPC_RH850_LOOP:
+	    	if (extract32(ctx->opcode, 11, 5) == 0x0)
+	    		gen_loop(ctx, rs1, ld_imm & 0xfffe);	// LOOP
+	    	else
+	    		gen_multiply(ctx, rs1, rs2, OPC_RH850_MULHI_imm16_reg1_reg2);
+	    	break;
+	    case OPC_RH850_BIT_MANIPULATION_2:
+
+	    	switch(extract32(ctx->opcode, 14, 2)){
+				case 0:
+					gen_bit_manipulation(ctx, rs1, rs2, OPC_RH850_SET1_bit3_disp16_reg1);
+					break;
+				case 1:
+					gen_bit_manipulation(ctx, rs1, rs2, OPC_RH850_NOT1_bit3_disp16_reg1);
+					break;
+				case 2:
+					gen_bit_manipulation(ctx, rs1, rs2, OPC_RH850_CLR1_bit3_disp16_reg1);
+					break;
+				case 3:
+					gen_bit_manipulation(ctx, rs1, rs2, OPC_RH850_TST1_bit3_disp16_reg1);
+					break;
+				}
+	    	break;
+		case OPC_RH850_32bit_1:		/* case for opcode = 111111 ; formats IX, X, XI, XII */
+			if (extract32(ctx->opcode, 16, 1) == 0x1 ) {
+                /* BCOND disp17 */
+				if (rs2 == 0x0)
+                {
+					/* Get condition. */
+					cond = extract32(ctx->opcode, 0, 4);
+
+					/* Extract immediate value (16 higher bits of 17 bits set by the instruction). */
+                    imm_32 = ((extract32(ctx->opcode, 4, 1)<<16) | (extract32(ctx->opcode, 17, 15) << 1));
+
+					/* Sign-extend value to 32 bits. */
+                    if ((imm_32 & 0x10000) == 0x10000)
+                    {
+                        imm_32 |= (0x7fff << 17);
+                    }
+
+					gen_branch(env, ctx, cond, rs1, rs2, imm_32);
+
+					break;
+				}
+                else
+                {
+					/* LD.HU */
+					gen_load(ctx, MO_TEUW, rs2, rs1, ld_imm & 0xfffe, 0);
+					break;
+				}
+			}
+			formXop = MASK_OP_32BIT_SUB(ctx->opcode);		//sub groups based on bits b23-b26
+			switch(formXop){
+				case OPC_RH850_LDSR_RIE_SETF_STSR:
+					check32bitZERO = extract32(ctx->opcode, 21, 2);
+					switch(check32bitZERO){
+					case 0:
+						if(extract32(ctx->opcode, 4, 1)==1)
+                        {
+							gen_special(ctx, env, rs1, rs2, OPC_RH850_RIE);
+						}
+                        else
+                        {
+                            printf("gen SETF\r\n");
+							gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_SETF_cccc_reg2);
+						}
+						break;
+					case OPC_RH850_LDSR_reg2_regID_selID:
+					    gen_special(ctx, env, rs1, rs2, OPC_RH850_LDSR_reg2_regID_selID);
+						break;
+					case OPC_RH850_STSR_regID_reg2_selID:
+						gen_special(ctx, env, rs1, rs2, OPC_RH850_STSR_regID_reg2_selID);
+						break;
+					}
+					break;
+				case OPC_RH850_FORMAT_IX:		//format IX instructions
+					formXop = MASK_OP_FORMAT_IX(ctx->opcode);	//mask on bits 21, 22
+					switch(formXop)
+                    {
+					case OPC_RH850_BINS_0:
+						if (extract32(ctx->opcode, 20, 1) == 1)
+                        {
+							//BINS0
+							gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_BINS);
+						}
+						else
+                        {
+							if (extract32(ctx->opcode, 17, 1) == 0)
+                            {
+								gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_SHR_reg1_reg2);
+							}
+                            else
+                            {
+								gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_SHR_reg1_reg2_reg3);
+							}
+						}
+						break;
+					case OPC_RH850_BINS_1:
+						if (extract32(ctx->opcode, 20, 1) == 1)
+                        {
+							//BINS1
+							gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_BINS);
+						}
+						else
+                        {
+							if (extract32(ctx->opcode, 17, 1) == 0)
+                            {
+								gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_SAR_reg1_reg2);
+							}
+                            else
+                            {
+								gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_SAR_reg1_reg2_reg3);
+							}
+						}
+					break;
+					case OPC_RH850_BINS_2:
+						if (extract32(ctx->opcode, 20, 1) == 1)
+                        {
+							//BINS2
+							gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_BINS);
+						}
+						else
+                        {
+							if (extract32(ctx->opcode, 17, 1) == 0)
+                            {
+								if (extract32(ctx->opcode, 18, 1) == 1)
+                                {
+									gen_data_manipulation(ctx, rs1, rs2,
+											OPC_RH850_ROTL_imm5_reg2_reg3);
+								}
+								else
+                                {
+									gen_data_manipulation(ctx, rs1, rs2,
+											OPC_RH850_SHL_reg1_reg2);
+								}
+							}
+                            else
+                            {
+								if (extract32(ctx->opcode, 18, 1) == 1)
+                                {
+									gen_data_manipulation(ctx, rs1, rs2,
+											OPC_RH850_ROTL_reg1_reg2_reg3);
+								}
+								else
+                                {
+									gen_data_manipulation(ctx, rs1, rs2,
+											OPC_RH850_SHL_reg1_reg2_reg3);
+								}
+							}
+						}
+						break;
+					case OPC_RH850_BIT_MANIPULATION: // in format IX
+						check32bitZERO = extract32(ctx->opcode, 16, 3);
+						switch(check32bitZERO){
+						case OPC_RH850_SET1_reg2_reg1:
+							gen_bit_manipulation(ctx, rs1, rs2, OPC_RH850_SET1_reg2_reg1);
+							break;
+						case OPC_RH850_NOT1_reg2_reg1:
+							gen_bit_manipulation(ctx, rs1, rs2, OPC_RH850_NOT1_reg2_reg1);
+							break;
+						case OPC_RH850_CLR1_reg2_reg1:
+							gen_bit_manipulation(ctx, rs1, rs2, OPC_RH850_CLR1_reg2_reg1);
+							break;
+						case OPC_RH850_TST1_reg2_reg1:
+							if (extract32(ctx->opcode, 19, 1) == 0){
+								gen_bit_manipulation(ctx, rs1, rs2, OPC_RH850_TST1_reg2_reg1);
+							} else {
+								gen_special(ctx, env, rs1, rs2, OPC_RH850_CAXI_reg1_reg2_reg3);
+							}
+						}
+						break;
+					}
+					break;
+
+
+				case OPC_RH850_FORMAT_X:		//format X instructions
+												//(+JARL3 - added due to MASK_OP_FORMAT_X matching)
+					formXop = MASK_OP_FORMAT_X(ctx->opcode);
+
+					switch(formXop){
+
+						case OPC_RH850_CTRET:
+							gen_special(ctx, env, rs1, rs2, OPC_RH850_CTRET);
+							break;
+						case OPC_RH850_DI:
+							gen_special(ctx, env, rs1, rs2, OPC_RH850_DI);
+							break;
+						case OPC_RH850_EI:
+							gen_special(ctx, env, rs1, rs2, OPC_RH850_EI);
+							break;
+						case OPC_RH850_EIRET:
+							gen_special(ctx, env, rs1, rs2, OPC_RH850_EIRET);
+							break;
+						case OPC_RH850_FERET:
+							gen_special(ctx, env, rs1, rs2, OPC_RH850_FERET);
+							break;
+						case OPC_RH850_HALT:
+							gen_special(ctx, env, rs1, rs2, OPC_RH850_HALT);
+							break;
+						case OPC_RH850_JARL3:
+							gen_jmp(ctx, rs1, 0, OPC_RH850_JARL_reg1_reg3);
+							break;
+						case OPC_RH850_SNOOZE:
+							gen_special(ctx, env, rs1, rs2, OPC_RH850_SNOOZE);
+							break;
+						case OPC_RH850_SYSCALL:
+							gen_special(ctx, env, rs1, rs2, OPC_RH850_SYSCALL);
+							break;
+						case OPC_RH850_TRAP:
+							gen_special(ctx, env, rs1, rs2, OPC_RH850_TRAP);
+							break;
+						case OPC_RH850_PREF:
+							//printf("PREF \n");
+							break;
+						case OPC_RH850_POPSP_rh_rt:
+							gen_special(ctx, env, rs1, rs2, OPC_RH850_POPSP_rh_rt);
+							break;
+						case OPC_RH850_PUSHSP_rh_rt:
+							gen_special(ctx, env, rs1, rs2, OPC_RH850_PUSHSP_rh_rt);
+							break;
+						default:
+							if ((extract32(ctx->opcode, 13, 12) == 0xB07))
+							{
+								if ((extract32(ctx->opcode, 27, 5) == 0x1E) &&
+									(extract32(ctx->opcode, 0, 5) == 0x1F))
+								{
+									if ((extract32(ctx->opcode, 23, 4) == 0x2)) // CLL
+										gen_mutual_exclusion(ctx, extract32(ctx->opcode, 27, 5), rs1, operation_CLL);
+								} else {
+									//CACHE; if cacheop bits are 1111110, opcode matches CLL ins,
+									//then they are THE SAME instruction, so this should be correct
+									gen_cache(ctx,rs1,rs2, 1);
+								}
+							} else
+								printf("ERROR! \n");
+						break;
+					}
+					break;
+				case OPC_RH850_MUL_INSTS:
+					if (extract32(ctx->opcode, 22, 1) == 0)
+                    {
+						if (extract32(ctx->opcode, 21, 1) == 0)
+                        {
+							gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_SASF_cccc_reg2);
+						}
+                        else
+                        {
+							if (extract32(ctx->opcode, 17, 1) == 1)
+                            {
+								gen_multiply(ctx, rs1, rs2, OPC_RH850_MULU_reg1_reg2_reg3);
+							}
+                            else
+                            {
+								gen_multiply(ctx, rs1, rs2, OPC_RH850_MUL_reg1_reg2_reg3);
+							}
+						}
+						break;
+					} else if (extract32(ctx->opcode, 22, 1) == 1)
+                    {
+						if (extract32(ctx->opcode, 17, 1) == 1)
+                        {
+							gen_multiply(ctx, rs1, rs2, OPC_RH850_MULU_imm9_reg2_reg3);
+						}
+                        else
+                        {
+							gen_multiply(ctx, rs1, rs2, OPC_RH850_MUL_imm9_reg2_reg3);
+						}
+						break;
+					}
+					break;
+
+				case OPC_RH850_FORMAT_XI:			// DIV instructions in format XI
+					formXop = extract32(ctx->opcode, 16, 7);
+					switch(formXop){
+
+						case OPC_RH850_DIV_reg1_reg2_reg3:
+							gen_divide(ctx, rs1, rs2, OPC_RH850_DIV_reg1_reg2_reg3);
+							//DIV
+							break;
+						case OPC_RH850_DIVH_reg1_reg2_reg3:
+							gen_divide(ctx, rs1, rs2, OPC_RH850_DIVH_reg1_reg2_reg3);
+							//DIVH 2
+							break;
+						case OPC_RH850_DIVHU_reg1_reg2_reg3:
+							gen_divide(ctx, rs1, rs2, OPC_RH850_DIVHU_reg1_reg2_reg3);
+							//DIVHU
+							break;
+
+						case OPC_RH850_DIVQ:
+							gen_divide(ctx, rs1, rs2, OPC_RH850_DIV_reg1_reg2_reg3);
+							//DIVQ => using DIV implementation, will be changed if needed
+							break;
+						case OPC_RH850_DIVQU:
+							gen_divide(ctx, rs1, rs2, OPC_RH850_DIVU_reg1_reg2_reg3);
+							//DIVQU => using DIVU implementation, will be changed if needed
+							break;
+						case OPC_RH850_DIVU_reg1_reg2_reg3:
+							gen_divide(ctx, rs1, rs2, OPC_RH850_DIVU_reg1_reg2_reg3);
+							//DIVU
+							break;
+					}
+					break;
+
+				case OPC_RH850_FORMAT_XII:	// for opcode = 0110 ; format XII instructions
+											//excluding MUL and including CMOV
+											// also LDL.W and STC.W	(Format VII)
+					checkXII = extract32(ctx->opcode, 21, 2);
+
+					switch(checkXII)
+                    {
+					case 0:
+						gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_CMOV_cccc_imm5_reg2_reg3);
+						break;
+					case 1:
+						gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_CMOV_cccc_reg1_reg2_reg3);
+						break;
+					case 2:
+						formXop = extract32(ctx->opcode, 17, 2);
+
+						switch(formXop)
+                        {
+						case OPC_RH850_BSW_reg2_reg3:
+							gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_BSW_reg2_reg3);
+							break;
+						case OPC_RH850_BSH_reg2_reg3:
+							gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_BSH_reg2_reg3);
+							break;
+						case OPC_RH850_HSW_reg2_reg3:
+							//HSW
+							gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_HSW_reg2_reg3);
+							break;
+						case OPC_RH850_HSH_reg2_reg3:
+							//HSH
+							gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_HSH_reg2_reg3);
+							break;
+						}
+						break;
+					case 3:	//these are SCHOL, SCHOR, SCH1L, SCH1R. 	Also LDL.W
+						formXop = extract32(ctx->opcode, 17, 2);
+						switch(formXop)
+                        {
+						case OPC_RH850_SCH0R_reg2_reg3:
+							if (extract32(ctx->opcode, 5, 11) == 0x3F &&
+									extract32(ctx->opcode, 16, 5) == 0x18)
+								gen_mutual_exclusion(ctx, extract32(ctx->opcode, 27, 5),
+										rs1, operation_LDL_W);
+							else
+								gen_bit_search(ctx, rs2, OPC_RH850_SCH0R_reg2_reg3);
+							break;
+						case OPC_RH850_SCH1R_reg2_reg3:
+							if (extract32(ctx->opcode, 19, 2) == 0x0)
+                            {
+								gen_bit_search(ctx, rs2, OPC_RH850_SCH1R_reg2_reg3);
+							}
+                            else if (extract32(ctx->opcode, 5, 11) == 0x3F &&
+									extract32(ctx->opcode, 16, 5) == 0x1a)
+								gen_mutual_exclusion(ctx, extract32(ctx->opcode, 27, 5),
+										rs1, operation_STC_W);
+							break;
+						case OPC_RH850_SCH0L_reg2_reg3:
+							gen_bit_search(ctx, rs2, OPC_RH850_SCH0L_reg2_reg3);
+							break;
+						case OPC_RH850_SCH1L_reg2_reg3:
+							gen_bit_search(ctx, rs2, OPC_RH850_SCH1L_reg2_reg3);
+							break;
+						}
+
+					}
+					break;
+
+				case OPC_RH850_ADDIT_ARITH:
+					formXop = extract32(ctx->opcode, 21, 2);
+					switch(formXop)
+                    {
+
+						case OPC_RH850_ADF_SATADD3:
+							if (extract32(ctx->opcode, 16, 5) == 0x1A)
+                            {
+								gen_sat_op(ctx, rs1, rs2, OPC_RH850_SATADD_reg1_reg2_reg3);
+							}
+                            else
+                            {
+								gen_cond_arith(ctx, rs1, rs2, OPC_RH850_ADF_cccc_reg1_reg2_reg3);
+							}
+							break;
+						case OPC_RH850_SBF_SATSUB:
+							if (extract32(ctx->opcode, 16, 5) == 0x1A)
+                            {
+								gen_sat_op(ctx, rs1, rs2, OPC_RH850_SATSUB_reg1_reg2_reg3);
+							}
+                            else
+                            {
+								gen_cond_arith(ctx, rs1, rs2, OPC_RH850_SBF_cccc_reg1_reg2_reg3);
+							}
+							break;
+						case OPC_RH850_MAC_reg1_reg2_reg3_reg4:
+							gen_mul_accumulate(ctx, rs1, rs2, OPC_RH850_MAC_reg1_reg2_reg3_reg4);
+							break;
+						case OPC_RH850_MACU_reg1_reg2_reg3_reg4:
+							gen_mul_accumulate(ctx, rs1, rs2, OPC_RH850_MACU_reg1_reg2_reg3_reg4);
+							break;
+					}
+                    break;
+
+                /* Floating-point instruction format F:I. */
+                case OPC_RH850_FORMAT_FI_CAT0:
+                {
+                    /* Dispatch to FPU generator (category 0). */
+                    fpu_decode_cat0_instn(env, ctx);
+                }
+                break;
+
+                case OPC_RH850_FORMAT_FI_CAT1:
+                {
+                    /* Dispatch to FPU generator (category 1). */
+                    fpu_decode_cat1_instn(env, ctx);
+                }
+                break;
+			}
+	}
+
+	if (MASK_OP_FORMAT_V_FORMAT_XIII(ctx->opcode) == OPC_RH850_FORMAT_V_XIII){
+		if(extract32(ctx->opcode, 16, 1) == 0)
+        {
+		    uint32_t disp22 = extract32(ctx->opcode, 16, 16) |
+		    		(extract32(ctx->opcode, 0, 6) << 16 );
+		    if( (disp22 & 0x200000) == 0x200000)
+            {
+		    	disp22 = disp22 | (0x3ff << 22);
+		    }
+
+			if (extract32(ctx->opcode, 11, 5) == 0)
+            {
+				gen_jmp(ctx, 0, disp22, OPC_RH850_JR_imm22);	//JR disp22
+			}
+            else
+            {
+				gen_jmp(ctx, 0, disp22, OPC_RH850_JARL_disp22_reg2);
+			}
+		}
+        else
+        {
+			if (extract32(ctx->opcode, 11, 5) != 0)
+            {
+				//LD.BU
+				gen_load(ctx, MO_UB, rs2, rs1, (ld_imm & 0xfffe) | extract32(ctx->opcode, 5, 1), 0);
+
+			}
+            else
+            {
+				if (extract32(ctx->opcode, 16, 3) == 0x3){
+					gen_special(ctx, env, rs1, rs2, OPC_RH850_PREPARE_list12_imm5_sp);
+					//PREPARE2
+				}
+				 else if (extract32(ctx->opcode, 16, 3) == 0x1){
+					 gen_special(ctx, env, rs1, rs2, OPC_RH850_PREPARE_list12_imm5);
+					 //PREPARE1
+				 }
+			}
+		}
+	}
+
+	tcg_temp_free(tcg_ctx, r1);
+    tcg_temp_free(tcg_ctx, r2);
+}
+
+/* 16-bit RH850 instruction decoding */
+static void decode_RH850_16(CPURH850State *env, DisasContext *ctx)
+{
+	int rs1;
+	int rs2;
+	int cond;
+	uint32_t op;
+	uint32_t subOpCheck;
+	uint32_t imm;
+	uint32_t disp32 = 0;
+
+	op = MASK_OP_MAJOR(ctx->opcode);
+	rs1 = GET_RS1(ctx->opcode);			// rs1 at bits b0-b4;
+	rs2 = GET_RS2(ctx->opcode);			// rs2 at bits b11-b15;
+	imm = rs1;
+
+	if((op & 0xf << 7) == OPC_RH850_BCOND )
+    { // checking for 4 bit opcode for BCOND
+		cond = extract32(ctx->opcode, 0, 4);
+		imm = ( extract32(ctx->opcode, 4, 3) | (extract32(ctx->opcode, 11, 5) << 3)) << 1 ;
+
+		if ( (imm & 0x100) == 0x100){
+			imm |=  (0x7fffff << 9);
+		}
+		gen_branch(env, ctx, cond, rs1, rs2, imm);
+
+		return;
+	}
+
+	switch(op)
+    {
+	case OPC_RH850_16bit_0:
+		if (rs2 != 0) {
+			gen_arithmetic(ctx, rs1, rs2, OPC_RH850_MOV_reg1_reg2);
+			break;
+		} else {
+			subOpCheck = MASK_OP_FORMAT_I_0(op);
+			switch(subOpCheck){
+				case OPC_RH850_NOP:
+					break;
+				case OPC_RH850_SYNCI:
+					break;
+				case OPC_RH850_SYNCE:
+					break;
+				case OPC_RH850_SYNCM:
+					break;
+				case OPC_RH850_SYNCP:
+					break;
+			}
+		}
+		break;
+
+	case OPC_RH850_16bit_2:
+		if (rs2 == 0)
+        {
+			if (rs1 == 0)
+            {
+				gen_special(ctx, env, rs1, rs2, OPC_RH850_RIE);
+				break;
+			}
+            else
+            {
+				gen_special(ctx, env, rs1, rs2, OPC_RH850_SWITCH_reg1);
+				break;
+			}
+		}
+        else
+        {
+			if (rs1 == 0)
+            {
+				gen_special(ctx, env, rs1, rs2, OPC_RH850_FETRAP_vector4);
+				break;
+			}
+            else
+            {
+				gen_divide(ctx, rs1, rs2, OPC_RH850_DIVH_reg1_reg2);
+				break;
+			}
+		}
+		break;
+
+	case OPC_RH850_16bit_4:
+		if (rs2 == 0)
+        {
+			gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_ZXB_reg1);
+			break;
+		}
+        else
+        {
+			gen_sat_op(ctx, rs1, rs2, OPC_RH850_SATSUBR_reg1_reg2);
+			break;
+		}
+		break;
+	case OPC_RH850_16bit_5:
+		if (rs2 == 0)
+        {
+			gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_SXB_reg1);
+			break;
+		}
+        else
+        {
+			gen_sat_op(ctx, rs1, rs2, OPC_RH850_SATSUB_reg1_reg2);
+			break;
+		}
+		break;
+	case OPC_RH850_16bit_6:
+		if (rs2 == 0)
+        {
+			gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_ZXH_reg1);
+			break;
+		}
+        else
+        {
+			gen_sat_op(ctx, rs1, rs2, OPC_RH850_SATADD_reg1_reg2);
+			break;
+		}
+		break;
+	case OPC_RH850_16bit_7:
+		if (rs2 == 0)
+        {
+			gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_SXH_reg1);
+			break;
+		}
+        else
+        {
+			gen_multiply(ctx, rs1, rs2, OPC_RH850_MULH_reg1_reg2);
+			break;
+		}
+		break;
+	case OPC_RH850_NOT_reg1_reg2:
+		gen_logical(ctx, rs1, rs2, OPC_RH850_NOT_reg1_reg2);
+		break;
+		// decode properly (handle also case when rs2 != 0), then uncomment
+        //	case OPC_RH850_JMP_DISP:
+		// JMP opcode: DDDD DDDD DDDD DDDD dddd dddd dddd ddd0 0000 0110 111R RRRR
+        //		disp32 = ctx->opcode >> 16;
+
+
+		// this case is already handled in decode_RH850_48()
+
+	case OPC_RH850_16bit_3:
+		if (rs2 == 0)
+        {   // JMP
+			gen_jmp(ctx, rs1, disp32, OPC_RH850_JMP_reg1);
+			break;
+		}
+        else
+        {
+			if(extract32(rs1,4,1)==1){
+				//SLD.HU
+				gen_load(ctx, MO_TEUW, rs2, 30, extract32(ctx->opcode, 0, 4) << 1, 0);
+			}else{
+				//SLD.BU
+				gen_load(ctx, MO_UB, rs2, 30, extract32(ctx->opcode, 0, 4), 0);
+			}
+			break;
+		}
+		break;
+	case OPC_RH850_OR_reg1_reg2:
+		gen_logical(ctx, rs1, rs2, OPC_RH850_OR_reg1_reg2);
+		break;
+	case OPC_RH850_XOR_reg1_reg2:
+		gen_logical(ctx, rs1, rs2, OPC_RH850_XOR_reg1_reg2);
+		break;
+	case OPC_RH850_AND_reg1_reg2:
+		gen_logical(ctx, rs1, rs2, OPC_RH850_AND_reg1_reg2);
+		break;
+	case OPC_RH850_TST_reg1_reg2:
+		gen_logical(ctx, rs1, rs2, OPC_RH850_TST_reg1_reg2);
+		break;
+	case OPC_RH850_SUBR_reg1_reg2:
+		gen_arithmetic(ctx, rs1, rs2, OPC_RH850_SUBR_reg1_reg2);
+		break;
+	case OPC_RH850_SUB_reg1_reg2:
+		gen_arithmetic(ctx, rs1, rs2, OPC_RH850_SUB_reg1_reg2);
+		break;
+	case OPC_RH850_ADD_reg1_reg2:
+		gen_arithmetic(ctx, rs1, rs2, OPC_RH850_ADD_reg1_reg2);
+		break;
+	case OPC_RH850_CMP_reg1_reg2:
+		gen_arithmetic(ctx, rs1, rs2, OPC_RH850_CMP_reg1_reg2);
+		break;
+	case OPC_RH850_16bit_16:
+		if (rs2 == 0)
+        {
+			gen_special(ctx, env, rs1, rs2, OPC_RH850_CALLT_imm6);
+			break;
+		}
+        else
+        {
+			gen_arithmetic(ctx, imm, rs2, OPC_RH850_MOV_imm5_reg2);
+			break;
+		}
+		break;
+	case OPC_RH850_16bit_17:
+		if (rs2 == 0)
+        {
+			gen_special(ctx, env, rs1, rs2, OPC_RH850_CALLT_imm6);
+			break;
+		}
+        else
+        {
+			gen_sat_op(ctx, rs1, rs2, OPC_RH850_SATADD_imm5_reg2);
+			break;
+		}
+		break;
+	case OPC_RH850_ADD_imm5_reg2:
+		gen_arithmetic(ctx, rs1, rs2, OPC_RH850_ADD_imm5_reg2);
+		break;
+	case OPC_RH850_CMP_imm5_reg2:
+		gen_arithmetic(ctx, rs1, rs2, OPC_RH850_CMP_imm5_reg2);
+		break;
+	case OPC_RH850_SHR_imm5_reg2:
+		gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_SHR_imm5_reg2);
+		break;
+	case OPC_RH850_SAR_imm5_reg2:
+		gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_SAR_imm5_reg2);
+		break;
+	case OPC_RH850_SHL_imm5_reg2:
+		gen_data_manipulation(ctx, rs1, rs2, OPC_RH850_SHL_imm5_reg2);
+		break;
+	case OPC_RH850_MULH_imm5_reg2:
+		gen_multiply(ctx, rs1, rs2, OPC_RH850_MULH_imm5_reg2);
+		break;
+	}
+
+	//Format IV ; dividing on code bits b7-b10
+	uint32_t opIV = (op >> 7);
+	opIV = opIV << 5;
+
+	switch(opIV)
+    {
+	case OPC_RH850_16bit_SLDB:
+		gen_load(ctx, MO_SB, rs2, 30, extract32(ctx->opcode, 0, 7), 0);
+		break;
+	case OPC_RH850_16bit_SLDH:
+		gen_load(ctx, MO_TESW, rs2, 30, extract32(ctx->opcode, 0, 7) << 1, 0);
+		break;
+	case OPC_RH850_16bit_IV10:
+		if ( extract32(rs1,0,1) == 1 ) {
+			//SST.W
+	    	gen_store(ctx, MO_TEUL, 30, rs2, (extract32(ctx->opcode, 1, 6)) << 2, 0);
+			/// Note An MAE or MDP exception might occur
+	    	/// depending on the result of address calculation.
+		}
+		else{
+			//SLD.W
+			gen_load(ctx, MO_TESL, rs2, 30, extract32(ctx->opcode, 1, 6) << 2, 0);
+		}
+		break;
+	case OPC_RH850_16bit_SSTB:
+    	gen_store(ctx, MO_UB, 30, rs2, (extract32(ctx->opcode, 0, 7)), 0);
+    	/// Note An MDP exception might occur depending on the result of address calculation.
+		break;
+	case OPC_RH850_16bit_SSTH:
+    	gen_store(ctx, MO_TEUW, 30, rs2, (extract32(ctx->opcode, 0, 7)) << 1, 0);
+    	/// Note An MAE or MDP exception might occur
+    	///depending on the result of address calculation.
+		break;
+	}
+}
+
+
+// ###################################################################################
+// ###################################################################################
+// ###################################################################################
+
+static void rh850_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
+{
+    DisasContext *dc = container_of(dcbase, DisasContext, base);
+    struct uc_struct *uc = cpu->uc;
+    dc->uc = uc;
+
+    CPURH850State *env = cpu->env_ptr;
+    dc->env = env;
+    dc->pc = dc->base.pc_first;
+}
+
+static void rh850_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
+{
+}
+
+static void rh850_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
+{
+    DisasContext *dc = container_of(dcbase, DisasContext, base);
+    TCGContext *tcg_ctx = dc->uc->tcg_ctx;
+
+    tcg_gen_insn_start(tcg_ctx, dc->base.pc_next);
+}
+
+/*
+ * This f. is called when breakpoint is hit. It should implement
+ * handling of breakpoint - for example HW breakpoints may be
+ * handled differently from SW breakpoints (see arm/translate.c).
+ * However, in RH850 we currently implement only SW breakpoints.
+ *
+ * Comment from translator.c:
+ *     The breakpoint_check hook may use DISAS_TOO_MANY to indicate
+ *     that only one more instruction is to be executed.  Otherwise
+ *     it should use DISAS_NORETURN when generating an exception,
+ *     but may use a DISAS_TARGET_* value for Something Else.
+ */
+static bool rh850_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
+                                     const CPUBreakpoint *bp)
+{
+    DisasContext *dc = container_of(dcbase, DisasContext, base);
+
+    gen_exception_debug(dc);
+    /* The address covered by the breakpoint must be included in
+       [tb->pc, tb->pc + tb->size) in order to for it to be
+       properly cleared -- thus we increment the PC here so that
+       the logic setting tb->size below does the right thing.  */
+    dc->base.pc_next += 2;
+    dc->base.is_jmp = DISAS_NORETURN;
+    return true;
+}
+
+/* RH850 instruction translation callback.  */
+static void rh850_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
+{
+    DisasContext *dc = container_of(dcbase, DisasContext, base);
+    struct uc_struct *uc = dc->uc;
+    TCGContext *tcg_ctx = uc->tcg_ctx;
+    TCGOp *tcg_op, *prev_op = NULL;
+    CPURH850State *env = dc->env;
+    bool insn_hook = false;
+
+    if (uc_addr_is_exit(dc->uc, dc->base.pc_next)) {
+        // imitate PGM exception to halt emulation
+        dcbase->is_jmp = DISAS_UNICORN_HALT;
+    }
+    else
+    {
+        #if 0
+        // Unicorn: trace this instruction on request
+        if (HOOK_EXISTS_BOUNDED(uc, UC_HOOK_CODE, dc->pc)) {
+
+            // Sync PC in advance
+            tcg_gen_movi_i32(tcg_ctx, cpu_pc, dc->pc);
+    
+            // save the last operand
+            prev_op = tcg_last_op(tcg_ctx);
+            insn_hook = true;
+    
+            gen_uc_tracecode(tcg_ctx, 0xF1F1F1F1, UC_HOOK_CODE_IDX, env->uc, dc->pc);
+            
+            // the callback might want to stop emulation immediately
+            check_exit_request(tcg_ctx);
+        }
+        #endif
+
+        dc->opcode = cpu_lduw_code(env, dc->pc);  // get opcode from memory
+
+        if ((extract32(dc->opcode, 9, 2) != 0x3) && (extract32(dc->opcode, 5, 11) != 0x17)) {
+            dc->base.pc_next = dc->pc + 2;
+            decode_RH850_16(env, dc);		//this function includes 32-bit JR and JARL
+        } else {
+            dc->opcode = (dc->opcode) | (cpu_lduw_code(env, dc->pc + 2) << 0x10);
+            if (((extract32(dc->opcode, 6, 11) == 0x41e) && ((extract32(dc->opcode, 17, 2) > 0x1) ||
+                                                            (extract32(dc->opcode, 17, 3) == 0x4))) ||
+                (extract32(dc->opcode, 5, 11) == 0x31) || // 48-bit MOV
+                (extract32(dc->opcode, 5, 12) == 0x37) || // 48-bit JMP
+                (extract32(dc->opcode, 5, 11) == 0x17) || // 48-bit JARL & JR
+                ((extract32(dc->opcode, 5, 11) == 0x3D) && (extract32(dc->opcode, 16, 5) == 0x07)) // 48-bit LD.HU
+            )
+            {
+                dc->opcode1 = cpu_lduw_code(env, dc->pc + 4);
+                dc->base.pc_next = dc->pc + 6;
+                decode_RH850_48(env, dc);
+            }
+            else
+            {
+                dc->base.pc_next = dc->pc + 4;
+                decode_RH850_32(env, dc);
+            }
+        }
+
+        #if 0
+        if (insn_hook) {
+            // Unicorn: patch the callback to have the proper instruction size.
+            if (prev_op) {
+                // As explained further up in the function where prev_op is
+                // assigned, we move forward in the tail queue, so we're modifying the
+                // move instruction generated by gen_uc_tracecode() that contains
+                // the instruction size to assign the proper size (replacing 0xF1F1F1F1).
+                tcg_op = QTAILQ_NEXT(prev_op, link);
+            } else {
+                // this instruction is the first emulated code ever,
+                // so the instruction operand is the first operand
+                tcg_op = QTAILQ_FIRST(&tcg_ctx->ops);
+            }
+
+            tcg_op->args[1] = dc->base.pc_next - dc->pc;
+        }
+        #endif
+
+        dc->pc = dc->base.pc_next;   
+    }
+}
+
+static void update_pc_addr(DisasContext *s)
+{
+    /* psw.addr */
+    TCGContext *tcg_ctx = s->uc->tcg_ctx;
+    tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_pc, s->base.pc_next);
+}
+
+// Emit exit TB code according to base.is_jmp
+static void rh850_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
+{
+    DisasContext *dc = container_of(dcbase, DisasContext, base);
+    TCGContext *tcg_ctx = dc->uc->tcg_ctx;
+
+    if (dc->base.is_jmp == DISAS_NORETURN)
+    {
+        return;
+    }
+    if (dc->base.singlestep_enabled) {
+    	if (dc->base.is_jmp == DISAS_NEXT  ||  dc->base.is_jmp == DISAS_TOO_MANY) {
+    		// PC is not loaded inside TB, so we have to do it here in case of
+    		// single stepping
+    	    tcg_gen_movi_tl(tcg_ctx, cpu_pc, dc->pc);
+    	}
+    	gen_exception_debug(dc);
+    }
+
+    switch (dc->base.is_jmp)
+    {
+    case DISAS_UNICORN_HALT:
+        tcg_gen_movi_tl(tcg_ctx, cpu_pc, dc->pc);
+        gen_exception_halt(dc);
+        break;
+    case DISAS_TOO_MANY:
+    case DISAS_PC_STALE:
+    case DISAS_PC_STALE_NOCHAIN:
+        update_pc_addr(dc);
+        gen_goto_tb_imm(dc, 0, dc->pc);
+        break;
+    case DISAS_INDIRECT_JUMP:
+        /* PC in CPURH850State must have been updated!  */
+        tcg_gen_lookup_and_goto_ptr(tcg_ctx);
+        break;
+    case DISAS_EXIT_TB:
+        tcg_gen_exit_tb(tcg_ctx, NULL, 0);
+        break;
+    case DISAS_NORETURN:
+    case DISAS_TB_EXIT_ALREADY_GENERATED:
+    	break;
+    default:
+        g_assert_not_reached();
+    }
+}
+
+static const TranslatorOps rh850_tr_ops = {
+    .init_disas_context = rh850_tr_init_disas_context,
+    .tb_start           = rh850_tr_tb_start,
+    .insn_start         = rh850_tr_insn_start,
+    .breakpoint_check   = rh850_tr_breakpoint_check,
+    .translate_insn     = rh850_tr_translate_insn,
+    .tb_stop            = rh850_tr_tb_stop,
+};
+
+/**
+ * This function translates one translation block (translation block
+ * is a sequence of instructions without jumps). Translation block
+ * is the longest translated sequence of instructions. The sequence
+ * may be shorter, if we are in singlestep mode (1 instruction), if
+ * breakpoint is detected, ... - see if statements, which break
+ * while loop below.
+ */
+
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
+{
+    DisasContext dc;
+    translator_loop(&rh850_tr_ops, &dc.base, cpu, tb, max_insns);
+}
+
+void rh850_translate_init(struct uc_struct *uc)
+{
+    TCGContext *tcg_ctx = uc->tcg_ctx;
+    int i;
+
+    /* cpu_gpr[0] is a placeholder for the zero register. Do not use it. */
+    /* Use the gen_set_gpr and gen_get_gpr helper functions when accessing */
+    /* registers, unless you specifically block writes to reg 0 */
+
+    for (i = 0; i < NUM_GP_REGS; i++) {
+        cpu_gpr[i] = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env,
+            offsetof(CPURH850State, gpRegs[i]), rh850_gp_regnames[i]);
+    }
+
+    for (int bankIdx = 0; bankIdx < NUM_SYS_REG_BANKS; bankIdx++) {
+        for (int regIdx = 0; regIdx < MAX_SYS_REGS_IN_BANK; regIdx++) {
+            const char *regName = rh850_sys_regnames[bankIdx][regIdx];
+            if (regName != NULL) {
+                cpu_sysRegs[bankIdx][regIdx] = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env,
+                                                                  offsetof(CPURH850State, systemRegs[bankIdx][regIdx]),
+                                                                  regName);
+            } else {
+                cpu_sysRegs[bankIdx][regIdx] = NULL;  // mark register as not present
+            }
+        }
+    }
+
+    for (i = 0; i < 1; i++) {
+        cpu_sysDatabuffRegs[i] = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env,
+            offsetof(CPURH850State, sysDatabuffRegs[i]), rh850_sys_databuff_regnames[i]);
+    }
+
+    // PSW register flags
+    cpu_ZF = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, Z_flag), "ZF");
+    cpu_SF = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, S_flag), "SF");
+	cpu_OVF = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, OV_flag), "OVF");
+	cpu_CYF = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, CY_flag), "CYF");
+	cpu_SATF = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, SAT_flag), "SAT");
+	cpu_ID = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, ID_flag), "ID");
+    cpu_EP = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, EP_flag), "EP");
+    cpu_NP = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, NP_flag), "NP");
+    cpu_EBV = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, EBV_flag), "EBV");
+    cpu_CU0 = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, CU0_flag), "CU0");
+    cpu_CU1 = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, CU1_flag), "CU1");
+    cpu_CU2 = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, CU2_flag), "CU2");
+    cpu_UM = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, UM_flag), "UM");
+
+    cpu_pc = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, pc), "pc");
+    load_res = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, load_res), "load_res");
+    load_val = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, load_val), "load_val");
+
+    cpu_LLbit = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, cpu_LLbit), "cpu_LLbit");
+    cpu_LLAddress = tcg_global_mem_new(tcg_ctx, tcg_ctx->cpu_env, offsetof(CPURH850State, cpu_LLAddress), "cpu_LLAddress");
+
+}
diff --git a/qemu/target/rh850/translate.h b/qemu/target/rh850/translate.h
new file mode 100644
index 0000000000..a622c4ce58
--- /dev/null
+++ b/qemu/target/rh850/translate.h
@@ -0,0 +1,35 @@
+#ifndef _RH850_TRANSLATE_H
+#define _RH850_TRANSLATE_H
+
+#include "cpu.h"
+#include "exec/translator.h"
+#include "tcg/tcg-op.h"
+
+/**
+ * This structure contains data, which is needed to translate a
+ * sequence of instructions, usually  inside one translation
+ * block. The most important member is therefore 'pc', which
+ * points to the instruction to be translated. This variable stores
+ * PC during compile time (guest instructions to TCG instructions).
+ * We must increment this variable manually during translation
+ * according to instruction size.
+ * Note: Consider renaming to TranslationContext, instead of DisasContext,
+ * because it contains information for translation, not disassembler.
+ */
+typedef struct DisasContext {
+    DisasContextBase base;
+    CPURH850State *env;
+    target_ulong pc;  // pointer to instruction being translated
+    uint32_t opcode;
+    uint32_t opcode1;  // used for 48 bit instructions
+
+    // Unicorn
+    struct uc_struct *uc;
+} DisasContext;
+
+void gen_get_gpr(TCGContext *tcg_ctx, TCGv t, int reg_num);
+void gen_set_gpr(TCGContext *tcg_ctx, int reg_num_dst, TCGv t);
+void gen_set_spr(TCGContext *tcg_ctx, int bank_id, int reg_id, TCGv t);
+void gen_get_spr(TCGContext *tcg_ctx, int bank_id, int reg_id, TCGv t);
+
+#endif /* _RH850_TRANSLATE_H */
\ No newline at end of file
diff --git a/qemu/target/rh850/unicorn.c b/qemu/target/rh850/unicorn.c
new file mode 100644
index 0000000000..362c92dc8c
--- /dev/null
+++ b/qemu/target/rh850/unicorn.c
@@ -0,0 +1,140 @@
+/* Unicorn Emulator Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015-2021 */
+/* Modified for Unicorn Engine by Damien Cauquil<dcauquil@quarkslab.com>, 2020 */
+
+#include "sysemu/cpus.h"
+#include "cpu.h"
+#include "unicorn_common.h"
+#include "uc_priv.h"
+#include "unicorn.h"
+
+RH850CPU *cpu_rh850_init(struct uc_struct *uc, const char *cpu_model);
+
+static void rh850_set_pc(struct uc_struct *uc, uint64_t address)
+{
+    ((CPURH850State *)uc->cpu->env_ptr)->pc = address;
+}
+
+static uint64_t rh850_get_pc(struct uc_struct *uc)
+{
+    return ((CPURH850State *)uc->cpu->env_ptr)->pc;
+}
+
+static void rh850_release(void *ctx)
+{
+
+    int i;
+    TCGContext *tcg_ctx = (TCGContext *)ctx;
+    RH850CPU *cpu = (RH850CPU *)tcg_ctx->uc->cpu;
+    CPUTLBDesc *d = cpu->neg.tlb.d;
+    CPUTLBDescFast *f = cpu->neg.tlb.f;
+    CPUTLBDesc *desc;
+    CPUTLBDescFast *fast;
+
+    release_common(ctx);
+    for (i = 0; i < NB_MMU_MODES; i++) {
+        desc = &(d[i]);
+        fast = &(f[i]);
+        g_free(desc->iotlb);
+        g_free(fast->table);
+    }
+}
+
+static void reg_reset(struct uc_struct *uc)
+{
+    CPUArchState *env = uc->cpu->env_ptr;
+
+    memset(env->gpRegs, 0, sizeof(env->gpRegs));
+    env->pc = 0;
+}
+
+DEFAULT_VISIBILITY
+uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, size_t *size)
+{
+    int sel_id;
+    CPURH850State *env = _env;
+    uc_err ret = UC_ERR_ARG;
+
+    /* PC */
+    if (regid == UC_RH850_REG_PC)
+    {
+        CHECK_REG_TYPE(uint32_t);
+        *(uint32_t *)value = env->pc;
+    }
+
+    /* General purpose register. */
+    if ((regid >= UC_RH850_REG_R0) && (regid <= UC_RH850_REG_R31))
+    {
+        CHECK_REG_TYPE(uint32_t);
+        *(uint32_t *)value = env->gpRegs[regid];
+    }
+
+    /* System registers. */
+    if ((regid >= UC_RH850_SYSREG_SELID0) && (regid < (UC_RH850_SYSREG_SELID7 + 32)))
+    {
+        CHECK_REG_TYPE(uint32_t);
+        sel_id = (regid - 32)/32;
+        *(uint32_t *)value = env->systemRegs[sel_id][regid % 32];
+    }
+
+    return ret;
+}
+
+
+DEFAULT_VISIBILITY
+uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, size_t *size, int *setpc)
+{
+    int sel_id;
+    CPURH850State *env = _env;
+    uc_err ret = UC_ERR_ARG;
+
+    /* PC */
+    if (regid == UC_RH850_REG_PC)
+    {
+        CHECK_REG_TYPE(uint32_t);
+        env->pc = *(uint32_t *)value;
+        *setpc = 1;
+    }
+
+    /* General purpose register. */
+    if ((regid >= UC_RH850_REG_R0) && (regid <= UC_RH850_REG_R31))
+    {
+        CHECK_REG_TYPE(uint32_t);
+        env->gpRegs[regid] = *(uint32_t *)value;
+    }
+
+    /* System registers. */
+    if ((regid >= UC_RH850_SYSREG_SELID0) && (regid <= (UC_RH850_SYSREG_SELID7 + 32)))
+    {
+        CHECK_REG_TYPE(uint32_t);
+        sel_id = (regid - 32)/32;
+        env->systemRegs[sel_id][regid % 32] = *(uint32_t *)value;
+    }
+
+    return ret;
+}
+
+static int rh850_cpus_init(struct uc_struct *uc, const char *cpu_model)
+{
+    RH850CPU *cpu;
+
+    cpu = cpu_rh850_init(uc, cpu_model);
+    if (cpu == NULL) {
+        return -1;
+    }
+    return 0;
+}
+
+DEFAULT_VISIBILITY
+void rh850_uc_init(struct uc_struct *uc)
+{
+    uc->reg_read = reg_read;
+    uc->reg_write = reg_write;
+    uc->reg_reset = reg_reset;
+    uc->release = rh850_release;
+    uc->set_pc = rh850_set_pc;
+    uc->get_pc = rh850_get_pc;
+    uc->cpus_init = rh850_cpus_init;
+    uc->cpu_context_size = offsetof(CPURH850State, uc);
+    uc_common_init(uc);
+}
diff --git a/qemu/target/rh850/unicorn.h b/qemu/target/rh850/unicorn.h
new file mode 100644
index 0000000000..7ce57301a4
--- /dev/null
+++ b/qemu/target/rh850/unicorn.h
@@ -0,0 +1,16 @@
+/* Unicorn Emulator Engine */
+/* By Damien Cauquil <dcauquil@quarkslab.com>, 2023 */
+
+#ifndef UC_QEMU_TARGET_RH850_H
+#define UC_QEMU_TARGET_RH850_H
+
+// functions to read & write registers
+uc_err reg_read_rh850(void *_env, int mode, unsigned int regid, void *value,
+                size_t *size);
+uc_err reg_write_rh850(void *_env, int mode, unsigned int regid, const void *value,
+                 size_t *size, int *setpc);
+
+void reg_reset_rh850(struct uc_struct *uc);
+
+void rh850_uc_init(struct uc_struct *uc);
+#endif
diff --git a/samples/sample_rh850.c b/samples/sample_rh850.c
new file mode 100644
index 0000000000..8f74bf5e77
--- /dev/null
+++ b/samples/sample_rh850.c
@@ -0,0 +1,118 @@
+/* Unicorn Emulator Engine */
+/* By Nguyen Anh Quynh, 2021 */
+
+/* Sample code to demonstrate how to emulate S390X code */
+
+#include <unicorn/unicorn.h>
+#include <string.h>
+
+// code to be emulated
+#define RH850_CODE "\x01\x0e\x06\x00\xc1\x11\x01\x1f\x00\x00\x41\x1f\x00\x00"
+
+// memory address where emulation starts
+#define ADDRESS 0x10000
+
+static void hook_block(uc_engine *uc, uint64_t address, uint32_t size,
+                       void *user_data)
+{
+    printf(">>> Tracing basic block at 0x%" PRIx64 ", block size = 0x%x\n",
+           address, size);
+}
+
+static void hook_code(uc_engine *uc, uint64_t address, uint32_t size,
+                      void *user_data)
+{
+    printf(">>> Tracing instruction at 0x%" PRIx64
+           ", instruction size = 0x%x\n",
+           address, size);
+}
+
+static void hook_mem64(uc_engine *uc, uc_mem_type type, uint64_t address,
+                       int size, int64_t value, void *user_data)
+{
+    uint64_t pc;
+    switch (type) {
+    default:
+        break;
+    case UC_MEM_READ:
+        uc_reg_read(uc, UC_RH850_REG_PC, &pc);
+        printf(">>> Memory read operation at 0x%" PRIx64 "\n", pc);
+        printf(">>> Memory is being READ at 0x%" PRIx64 ", data size = %u\n",
+               address, size);
+        break;
+    case UC_MEM_WRITE:
+        uc_reg_read(uc, UC_RH850_REG_PC, &pc);
+        printf(">>> Memory write operation at 0x%" PRIx64 "\n", pc);
+        printf(">>> Memory is being WRITE at 0x%" PRIx64
+               ", data size = %u, data value = 0x%" PRIx64 "\n",
+               address, size, value);
+        break;
+    }
+}
+
+
+static void test_rh850(void)
+{
+    uc_engine *uc;
+    uc_hook trace1, trace2, trace3;
+    uc_err err;
+
+    uint64_t r1 = 0x10000, r2 = 3, r3;
+
+    printf("Emulate RH850 code\n");
+
+    // Initialize emulator in S390X mode
+    err = uc_open(UC_ARCH_RH850, UC_MODE_LITTLE_ENDIAN, &uc);
+    if (err) {
+        printf("Failed on uc_open() with error returned: %u (%s)\n", err,
+               uc_strerror(err));
+        return;
+    }
+
+    // map 1MB memory for this emulation
+    uc_mem_map(uc, ADDRESS, 1024 * 1024, UC_PROT_ALL);
+
+    // write machine code to be emulated to memory
+    uc_mem_write(uc, ADDRESS, RH850_CODE, sizeof(RH850_CODE) - 1);
+
+    // initialize machine registers
+    uc_reg_write(uc, UC_RH850_REG_R1, &r1);
+    uc_reg_write(uc, UC_RH850_REG_R2, &r2);
+
+    // tracing all basic blocks with customized callback
+    uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
+
+    // tracing all instruction
+    uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0);
+
+    // tracing mem read
+    uc_hook_add(uc, &trace3, UC_HOOK_MEM_READ, hook_mem64, NULL, 1, 0);
+    uc_hook_add(uc, &trace3, UC_HOOK_MEM_WRITE, hook_mem64, NULL, 1, 0);
+
+    // emulate machine code in infinite time (last param = 0), or when
+    // finishing all the code.
+    err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(RH850_CODE) - 1, 0, 0);
+    if (err) {
+        printf("Failed on uc_emu_start() with error returned: %u (%s)\n", err,
+               uc_strerror(err));
+    }
+
+    // now print out some registers
+    printf(">>> Emulation done. Below is the CPU context\n");
+
+    uc_reg_read(uc, UC_RH850_REG_R1, &r1);
+    uc_reg_read(uc, UC_RH850_REG_R2, &r2);
+    uc_reg_read(uc, UC_RH850_REG_R3, &r3);
+
+    printf(">>> R1 = 0x%" PRIx64 "\t\t>>> R2 = 0x%" PRIx64 "\n", r1, r2);
+    printf(">>> R3 = 0x%" PRIx64 "\n", r3);
+
+    uc_close(uc);
+}
+
+int main(int argc, char **argv, char **envp)
+{
+    test_rh850();
+
+    return 0;
+}
diff --git a/symbols.sh b/symbols.sh
index e038b46fb3..456922703b 100755
--- a/symbols.sh
+++ b/symbols.sh
@@ -6268,6 +6268,12 @@ tcg_s390_program_interrupt \
 tcg_s390_data_exception \
 "
 
+rh850_SYMBOLS="restore_state_to_opc \
+helper_tlb_flush \
+helper_uc_rh850_exit \
+gen_intermediate_code \
+"
+
 tricore_SYMBOLS="
 helper_fadd \
 helper_fsub \
@@ -6281,7 +6287,7 @@ restore_state_to_opc \
 helper_uc_tricore_exit \
 "
 
-ARCHS="x86_64 arm aarch64 riscv32 riscv64 mips mipsel mips64 mips64el sparc sparc64 m68k ppc ppc64 s390x tricore"
+ARCHS="x86_64 arm aarch64 rh850 riscv32 riscv64 mips mipsel mips64 mips64el sparc sparc64 m68k ppc ppc64 s390x tricore"
 
 for arch in $ARCHS; do
 
diff --git a/tests/unit/test_rh850.c b/tests/unit/test_rh850.c
new file mode 100644
index 0000000000..e02e704167
--- /dev/null
+++ b/tests/unit/test_rh850.c
@@ -0,0 +1,40 @@
+#include "unicorn_test.h"
+
+const uint64_t code_start = 0x1000;
+const uint64_t code_len = 0x4000;
+
+static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
+                            const char *code, uint64_t size)
+{
+    OK(uc_open(arch, mode, uc));
+    OK(uc_mem_map(*uc, code_start, code_len, UC_PROT_ALL));
+    OK(uc_mem_write(*uc, code_start, code, size));
+}
+
+static void test_rh850_add(void)
+{
+    char code[] = "\x01\x0e\x06\x00\xc1\x11"; 
+    uint32_t r1 = 0x1234;
+    uint32_t r2 = 0x7777;
+    uint32_t pc;
+    uc_engine *uc;
+
+    uc_common_setup(&uc, UC_ARCH_RH850, UC_MODE_LITTLE_ENDIAN, code,
+                    sizeof(code) - 1);
+    OK(uc_reg_write(uc, UC_RH850_REG_R1, &r1));
+    OK(uc_reg_write(uc, UC_RH850_REG_R2, &r2));
+
+    OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
+
+    OK(uc_reg_read(uc, UC_RH850_REG_R1, &r1));
+    OK(uc_reg_read(uc, UC_RH850_REG_R2, &r2));
+    OK(uc_reg_read(uc, UC_RH850_REG_PC, &pc));
+
+    TEST_CHECK(r1 == 0x1234 + 6);
+    TEST_CHECK(r2 == 0x89b1);
+    TEST_CHECK(pc == code_start + sizeof(code) - 1);
+
+    OK(uc_close(uc));
+}
+
+TEST_LIST = {{"test_rh850_add", test_rh850_add}, {NULL, NULL}};
\ No newline at end of file
diff --git a/uc.c b/uc.c
index 1098344711..ae961ede49 100644
--- a/uc.c
+++ b/uc.c
@@ -23,6 +23,7 @@
 #include "qemu/target/mips/unicorn.h"
 #include "qemu/target/sparc/unicorn.h"
 #include "qemu/target/ppc/unicorn.h"
+#include "qemu/target/rh850/unicorn.h"
 #include "qemu/target/riscv/unicorn.h"
 #include "qemu/target/s390x/unicorn.h"
 #include "qemu/target/tricore/unicorn.h"
@@ -187,6 +188,10 @@ bool uc_arch_supported(uc_arch arch)
     case UC_ARCH_X86:
         return true;
 #endif
+#ifdef UNICORN_HAS_RH850
+    case UC_ARCH_RH850:
+        return true;
+#endif
 #ifdef UNICORN_HAS_RISCV
     case UC_ARCH_RISCV:
         return true;
@@ -401,6 +406,15 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result)
             }
             break;
 #endif
+#ifdef UNICORN_HAS_RH850
+        case UC_ARCH_RH850:
+            if (mode != UC_MODE_LITTLE_ENDIAN) {
+                free(uc);
+                return UC_ERR_MODE;
+            }
+            uc->init_arch = rh850_uc_init;
+            break;
+#endif
 #ifdef UNICORN_HAS_RISCV
         case UC_ARCH_RISCV:
             if ((mode & ~UC_MODE_RISCV_MASK) ||
@@ -971,6 +985,11 @@ uc_err uc_emu_start(uc_engine *uc, uint64_t begin, uint64_t until,
         }
         break;
 #endif
+#ifdef UNICORN_HAS_RH850
+    case UC_ARCH_RH850:
+        uc_reg_write(uc, UC_RH850_REG_PC, &begin);
+        break;
+#endif
 #ifdef UNICORN_HAS_RISCV
     case UC_ARCH_RISCV:
         if (uc->mode & UC_MODE_RISCV64) {
@@ -1046,6 +1065,7 @@ uc_err uc_emu_start(uc_engine *uc, uint64_t begin, uint64_t until,
 
     if (timeout) {
         // wait for the timer to finish
+        printf("Wait VM to finish ...\n");
         qemu_thread_join(&uc->timer);
     }
 
@@ -2130,6 +2150,12 @@ static context_reg_rw_t find_context_reg_rw(uc_arch arch, uc_mode mode)
         }
         break;
 #endif
+#ifdef UNICORN_HAS_RH850
+    case UC_ARCH_RH850:
+        rw.read = reg_read_rh850;
+        rw.write = reg_write_rh850;
+        break;
+#endif
 #ifdef UNICORN_HAS_RISCV
     case UC_ARCH_RISCV:
         if (mode & UC_MODE_RISCV32) {