All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/3] MIPS decodetree conversion attempt
@ 2022-09-21 12:41 Jiaxun Yang
  2022-09-21 12:41 ` [RFC PATCH 1/3] target/mips: Introduce register access helper functions Jiaxun Yang
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Jiaxun Yang @ 2022-09-21 12:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: f4bug, richard.henderson, Jiaxun Yang

Hi,

This is my attempt of converting MIPS translation code into decodetree.

Currently only MIPS I to MIPS Release 5 arithmatic functions are converted.
Old decoding functions are perserved in codebase for now due to dependencies
from microMIPS/nanoMIPS translation code. Will remove them after dealing with
release 6.

Both instruction encoding and test cases are generated form MIPS's internal
architecture validation tools so they are gureented to be correct.

Thanks.

- Jiaxun

Jiaxun Yang (3):
  target/mips: Introduce register access helper functions
  target/mips: Convert legacy arithmatic instructions to decodetree
  tests/tcg/mips: Add mips32 arithmatic instruction test cases

 target/mips/tcg/insn_trans/trans_arith.c.inc  | 352 ++++++++++++++++++
 target/mips/tcg/legacy.decode                 |  62 +++
 target/mips/tcg/meson.build                   |   1 +
 target/mips/tcg/translate.c                   | 143 ++++++-
 target/mips/tcg/translate.h                   |  54 +++
 tests/tcg/mips/include/test_utils_32.h        |  75 ++++
 .../tcg/mips/user/isa/mips32/arithmatic/add.c |  99 +++++
 .../mips/user/isa/mips32/arithmatic/addi.c    |  70 ++++
 .../mips/user/isa/mips32/arithmatic/addiu.c   |  90 +++++
 .../mips/user/isa/mips32/arithmatic/addu.c    | 125 +++++++
 .../tcg/mips/user/isa/mips32/arithmatic/div.c |  81 ++++
 .../mips/user/isa/mips32/arithmatic/divu.c    |  78 ++++
 .../mips/user/isa/mips32/arithmatic/madd.c    |  79 ++++
 .../mips/user/isa/mips32/arithmatic/maddu.c   |  78 ++++
 .../mips/user/isa/mips32/arithmatic/msub.c    |  78 ++++
 .../mips/user/isa/mips32/arithmatic/msubu.c   |  78 ++++
 .../tcg/mips/user/isa/mips32/arithmatic/mul.c |  78 ++++
 .../mips/user/isa/mips32/arithmatic/mult.c    |  78 ++++
 .../mips/user/isa/mips32/arithmatic/multu.c   |  78 ++++
 .../tcg/mips/user/isa/mips32/arithmatic/slt.c |  61 +++
 .../mips/user/isa/mips32/arithmatic/slti.c    |  48 +++
 .../mips/user/isa/mips32/arithmatic/sltiu.c   |  48 +++
 .../mips/user/isa/mips32/arithmatic/sltu.c    |  61 +++
 .../tcg/mips/user/isa/mips32/arithmatic/sub.c | 104 ++++++
 .../mips/user/isa/mips32/arithmatic/subu.c    | 108 ++++++
 25 files changed, 2206 insertions(+), 1 deletion(-)
 create mode 100644 target/mips/tcg/insn_trans/trans_arith.c.inc
 create mode 100644 target/mips/tcg/legacy.decode
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/add.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addi.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/div.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/divu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/madd.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/maddu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msubu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mul.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mult.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/multu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slt.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slti.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/subu.c

-- 
2.34.1



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

* [RFC PATCH 1/3] target/mips: Introduce register access helper functions
  2022-09-21 12:41 [RFC PATCH 0/3] MIPS decodetree conversion attempt Jiaxun Yang
@ 2022-09-21 12:41 ` Jiaxun Yang
  2022-09-21 12:41 ` [RFC PATCH 2/3] target/mips: Convert legacy arithmatic instructions to decodetree Jiaxun Yang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2022-09-21 12:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: f4bug, richard.henderson, Jiaxun Yang

Introduce register access functions with value extend capability
to prepare for decodetree based translation implmentation.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 target/mips/tcg/translate.c | 143 +++++++++++++++++++++++++++++++++++-
 target/mips/tcg/translate.h |  54 ++++++++++++++
 2 files changed, 196 insertions(+), 1 deletion(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index de1511baaf..b5d595ef34 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -1196,6 +1196,17 @@ enum {
     MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
 };
 
+/*
+ * If an operation is being performed on less than TARGET_LONG_BITS,
+ * it may require the inputs to be sign- or zero-extended; which will
+ * depend on the exact operation being performed.
+ */
+typedef enum {
+    EXT_NONE,
+    EXT_SIGN,
+    EXT_ZERO
+} DisasExtend;
+
 /* global register indices */
 TCGv cpu_gpr[32], cpu_PC;
 /*
@@ -1221,6 +1232,18 @@ static const char regnames_LO[][4] = {
     "LO0", "LO1", "LO2", "LO3",
 };
 
+static TCGv ctx_temp_new(DisasContext *ctx)
+{
+    assert(ctx->ntemp < ARRAY_SIZE(ctx->temp));
+    return ctx->temp[ctx->ntemp++] = tcg_temp_new();
+}
+
+static TCGv_i64 ctx_temp_new_i64(DisasContext *ctx)
+{
+    assert(ctx->ntemp64 < ARRAY_SIZE(ctx->temp64));
+    return ctx->temp64[ctx->ntemp64++] = tcg_temp_new_i64();
+}
+
 /* General purpose registers moves. */
 void gen_load_gpr(TCGv t, int reg)
 {
@@ -1238,6 +1261,106 @@ void gen_store_gpr(TCGv t, int reg)
     }
 }
 
+void gen_extend(TCGv dst, TCGv src, DisasExtend src_ext)
+{
+    switch (src_ext) {
+    case EXT_NONE:
+        tcg_gen_mov_tl(dst, src);
+        return;
+    case EXT_SIGN:
+        tcg_gen_ext32s_tl(dst, src);
+        return;
+    case EXT_ZERO:
+        tcg_gen_ext32u_tl(dst, src);
+        return;
+    }
+    g_assert_not_reached();
+}
+
+TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend src_ext)
+{
+    TCGv t;
+
+    if (reg_num == 0) {
+        return ctx->zero;
+    }
+
+    switch (src_ext) {
+    case EXT_NONE:
+        return cpu_gpr[reg_num];
+    default:
+        t = ctx_temp_new(ctx);
+        gen_extend(t, cpu_gpr[reg_num], src_ext);
+        return t;
+    }
+}
+
+TCGv_i64 get_hilo(DisasContext *ctx, int acc)
+{
+    TCGv_i64 t = ctx_temp_new_i64(ctx);
+    /* acc must be 0 when DSP is not implemented */
+    g_assert(acc == 0 || ctx->insn_flags & ASE_DSP);
+    tcg_gen_concat_tl_i64(t, cpu_LO[acc], cpu_HI[acc]);
+
+    return t;
+}
+
+TCGv dest_gpr(DisasContext *ctx, int reg_num)
+{
+    if (reg_num == 0) {
+        return ctx_temp_new(ctx);
+    }
+    return cpu_gpr[reg_num];
+}
+
+TCGv dest_lo(DisasContext *ctx, int acc)
+{
+    /* acc must be 0 when DSP is not implemented */
+    g_assert(acc == 0 || ctx->insn_flags & ASE_DSP);
+
+    return cpu_LO[acc];
+}
+
+TCGv dest_hi(DisasContext *ctx, int acc)
+{
+    /* acc must be 0 when DSP is not implemented */
+    g_assert(acc == 0 || ctx->insn_flags & ASE_DSP);
+
+    return cpu_HI[acc];
+}
+
+/* For 32 bit hilo pair */
+TCGv_i64 dest_hilo(DisasContext *ctx, int acc)
+{
+    /* acc must be 0 when DSP is not implemented */
+    g_assert(acc == 0 || ctx->insn_flags & ASE_DSP);
+    return ctx_temp_new_i64(ctx);
+}
+
+void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext)
+{
+    if (reg_num != 0) {
+        gen_extend(cpu_gpr[reg_num], t, dst_ext);
+    }
+}
+
+void gen_set_lo(int acc, TCGv t, DisasExtend dst_ext)
+{
+    gen_extend(cpu_LO[acc], t, dst_ext);
+}
+
+void gen_set_hi(int acc, TCGv t, DisasExtend dst_ext)
+{
+    gen_extend(cpu_HI[acc], t, dst_ext);
+}
+
+/* For 32 bit hilo pair */
+void gen_set_hilo(int acc, TCGv_i64 t)
+{
+    gen_move_low32(cpu_LO[acc], t);
+    gen_move_high32(cpu_HI[acc], t);
+}
+
 #if defined(TARGET_MIPS64)
 void gen_load_gpr_hi(TCGv_i64 t, int reg)
 {
@@ -2615,7 +2738,6 @@ static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
     tcg_temp_free(t0);
 }
 
-/* Arithmetic */
 static void gen_arith(DisasContext *ctx, uint32_t opc,
                       int rd, int rs, int rt)
 {
@@ -16031,6 +16153,12 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
         ctx->base.max_insns = 2;
     }
 
+    ctx->ntemp = 0;
+    ctx->ntemp64 = 0;
+    memset(ctx->temp, 0, sizeof(ctx->temp));
+    memset(ctx->temp64, 0, sizeof(ctx->temp));
+    ctx->zero = tcg_constant_tl(0);
+
     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
               ctx->hflags);
 }
@@ -16053,6 +16181,7 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
     DisasContext *ctx = container_of(dcbase, DisasContext, base);
     int insn_bytes;
     int is_slot;
+    int i;
 
     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
     if (ctx->insn_flags & ISA_NANOMIPS32) {
@@ -16074,6 +16203,18 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
         return;
     }
 
+    for (i = ctx->ntemp - 1; i >= 0; --i) {
+        tcg_temp_free(ctx->temp[i]);
+        ctx->temp[i] = NULL;
+        ctx->ntemp--;
+    }
+
+    for (i = ctx->ntemp64 - 1; i >= 0; --i) {
+        tcg_temp_free_i64(ctx->temp64[i]);
+        ctx->temp64[i] = NULL;
+        ctx->ntemp64--;
+    }
+
     if (ctx->hflags & MIPS_HFLAG_BMASK) {
         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
                              MIPS_HFLAG_FBNSLOT))) {
diff --git a/target/mips/tcg/translate.h b/target/mips/tcg/translate.h
index 69f85841d2..980aa8682d 100644
--- a/target/mips/tcg/translate.h
+++ b/target/mips/tcg/translate.h
@@ -49,6 +49,11 @@ typedef struct DisasContext {
     bool saar;
     bool mi;
     int gi;
+    TCGv zero;
+    TCGv temp[4];
+    uint8_t ntemp;
+    TCGv_i64 temp64[4];
+    uint8_t ntemp64;
 } DisasContext;
 
 #define DISAS_STOP       DISAS_TARGET_0
@@ -119,6 +124,17 @@ enum {
     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
 };
 
+/*
+ * If an operation is being performed on less than TARGET_LONG_BITS,
+ * it may require the inputs to be sign- or zero-extended; which will
+ * depend on the exact operation being performed.
+ */
+typedef enum {
+    EXT_NONE,
+    EXT_SIGN,
+    EXT_ZERO
+} DisasExtend;
+
 #define gen_helper_0e1i(name, arg1, arg2) do { \
     gen_helper_##name(cpu_env, arg1, tcg_constant_i32(arg2)); \
     } while (0)
@@ -150,6 +166,18 @@ void check_cp1_64bitmode(DisasContext *ctx);
 void check_cp1_registers(DisasContext *ctx, int regs);
 void check_cop1x(DisasContext *ctx);
 
+void gen_extend(TCGv dst, TCGv src, DisasExtend src_ext);
+TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend src_ext);
+TCGv_i64 get_hilo(DisasContext *ctx, int acc);
+TCGv dest_gpr(DisasContext *ctx, int reg_num);
+TCGv dest_lo(DisasContext *ctx, int acc);
+TCGv dest_hi(DisasContext *ctx, int acc);
+TCGv_i64 dest_hilo(DisasContext *ctx, int acc);
+void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext);
+void gen_set_lo(int acc, TCGv t, DisasExtend dst_ext);
+void gen_set_hi(int acc, TCGv t, DisasExtend dst_ext);
+void gen_set_hilo(int acc, TCGv_i64 t);
+
 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset);
 void gen_move_low32(TCGv ret, TCGv_i64 arg);
 void gen_move_high32(TCGv ret, TCGv_i64 arg);
@@ -231,6 +259,32 @@ bool decode_ext_vr54xx(DisasContext *ctx, uint32_t insn);
     static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
     { return FUNC(ctx, a, __VA_ARGS__); }
 
+/* Instructions removed in Release 6 */
+#define TRANS_6R(NAME, FUNC, ...) \
+    static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
+    { return !(ctx->insn_flags & ISA_MIPS_R6) & FUNC(ctx, a, __VA_ARGS__); }
+
+#if defined(TARGET_MIPS64)
+#define TRANS64(NAME, FUNC, ...) \
+    static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
+    { check_mips_64(ctx); return FUNC(ctx, a, __VA_ARGS__); }
+#define TRANS64_6R(NAME, FUNC, ...) \
+    static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
+    { if (ctx->insn_flags & ISA_MIPS_R6) return false; check_mips_64(ctx); \
+    return FUNC(ctx, a, __VA_ARGS__); }
+#else
+#define TRANS64(NAME, FUNC, ...) \
+    static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
+    { return false; }
+#define TRANS64_6R(NAME, FUNC, ...) \
+    static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
+    { return false; }
+#endif
+
+#define TRANS_FLAGS(NAME, FLAGS, ...) \
+    static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
+    { return (ctx->insn_flags & FLAGS) && FUNC(s, __VA_ARGS__); }
+
 static inline bool cpu_is_bigendian(DisasContext *ctx)
 {
     return extract32(ctx->CP0_Config0, CP0C0_BE, 1);
-- 
2.34.1



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

* [RFC PATCH 2/3] target/mips: Convert legacy arithmatic instructions to decodetree
  2022-09-21 12:41 [RFC PATCH 0/3] MIPS decodetree conversion attempt Jiaxun Yang
  2022-09-21 12:41 ` [RFC PATCH 1/3] target/mips: Introduce register access helper functions Jiaxun Yang
@ 2022-09-21 12:41 ` Jiaxun Yang
  2022-09-21 12:41 ` [RFC PATCH 3/3] tests/tcg/mips: Add mips32 arithmatic instruction test cases Jiaxun Yang
  2022-09-26 14:44 ` [RFC PATCH 0/3] MIPS decodetree conversion attempt Jiaxun Yang
  3 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2022-09-21 12:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: f4bug, richard.henderson, Jiaxun Yang

Mostly copy paste from translate.c, with some simplification
based on newly introduced register access functions.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 target/mips/tcg/insn_trans/trans_arith.c.inc | 352 +++++++++++++++++++
 target/mips/tcg/legacy.decode                |  62 ++++
 target/mips/tcg/meson.build                  |   1 +
 target/mips/tcg/translate.c                  |  20 +-
 4 files changed, 425 insertions(+), 10 deletions(-)
 create mode 100644 target/mips/tcg/insn_trans/trans_arith.c.inc
 create mode 100644 target/mips/tcg/legacy.decode

diff --git a/target/mips/tcg/insn_trans/trans_arith.c.inc b/target/mips/tcg/insn_trans/trans_arith.c.inc
new file mode 100644
index 0000000000..3de9722939
--- /dev/null
+++ b/target/mips/tcg/insn_trans/trans_arith.c.inc
@@ -0,0 +1,352 @@
+static bool gen_arith_notrap(DisasContext *ctx, arg_r *a,
+                             DisasExtend ext, void (*func)(TCGv, TCGv, TCGv))
+{
+    TCGv dest = dest_gpr(ctx, a->rd);
+    TCGv src1 = get_gpr(ctx, a->rs, ext);
+    TCGv src2 = get_gpr(ctx, a->rt, ext);
+
+    func(dest, src1, src2);
+    gen_set_gpr(a->rd, dest, ext);
+
+    return true;
+}
+
+static bool gen_add(DisasContext *ctx, arg_r *a, DisasExtend ext)
+{
+    TCGv t0 = tcg_temp_local_new();
+    TCGv t1 = get_gpr(ctx, a->rs, ext);
+    TCGv t2 = get_gpr(ctx, a->rt, ext);
+    TCGLabel *l1 = gen_new_label();
+
+    tcg_gen_add_tl(t0, t1, t2);
+    gen_extend(t0, t0, ext);
+    tcg_gen_xor_tl(t1, t1, t2);
+    tcg_gen_xor_tl(t2, t0, t2);
+    tcg_gen_andc_tl(t1, t2, t1);
+    tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
+    /* operands of same sign, result different sign */
+    generate_exception(ctx, EXCP_OVERFLOW);
+    gen_set_label(l1);
+    gen_store_gpr(t0, a->rd);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool gen_sub(DisasContext *ctx, arg_r *a, DisasExtend ext)
+{
+    TCGv src1 = get_gpr(ctx, a->rs, ext);
+    TCGv src2 = get_gpr(ctx, a->rt, ext);
+    TCGv t0 = tcg_temp_local_new();
+    TCGv t1 = tcg_temp_local_new();
+    TCGv t2 = tcg_temp_local_new();
+    TCGLabel *l1 = gen_new_label();
+
+    tcg_gen_sub_tl(t0, src1, src2);
+    gen_extend(t0, t0, ext);
+    tcg_gen_xor_tl(t2, src1, src2);
+    tcg_gen_xor_tl(t1, t0, src1);
+    tcg_gen_and_tl(t1, t1, t2);
+    tcg_temp_free(t2);
+    tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
+    tcg_temp_free(t1);
+    /*
+     * operands of different sign, first operand and the result
+     * of different sign
+     */
+    generate_exception(ctx, EXCP_OVERFLOW);
+    gen_set_label(l1);
+    gen_store_gpr(t0, a->rd);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool gen_arith_imm_notrap(DisasContext *ctx, arg_i *a, DisasExtend ext,
+                             void (*func)(TCGv, TCGv, target_long))
+{
+    TCGv dest = dest_gpr(ctx, a->rt);
+    TCGv src1 = get_gpr(ctx, a->rs, ext);
+
+    func(dest, src1, a->imm);
+    gen_set_gpr(a->rt, dest, ext);
+
+    return true;
+}
+
+static bool gen_add_imm(DisasContext *ctx, arg_i *a, DisasExtend ext)
+{
+    TCGv t0 = tcg_temp_local_new();
+    TCGv t1 = get_gpr(ctx, a->rs, ext);
+    TCGv t2 = tcg_temp_new();
+    TCGLabel *l1 = gen_new_label();
+    target_ulong uimm = (target_long)a->imm; /* Sign extend to 32/64 bits */
+
+    gen_load_gpr(t1, a->rs);
+    tcg_gen_addi_tl(t0, t1, uimm);
+    tcg_gen_ext32s_tl(t0, t0);
+
+    tcg_gen_xori_tl(t1, t1, ~uimm);
+    tcg_gen_xori_tl(t2, t0, uimm);
+    tcg_gen_and_tl(t1, t1, t2);
+    tcg_temp_free(t2);
+    tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
+    /* operands of same sign, result different sign */
+    generate_exception(ctx, EXCP_OVERFLOW);
+    gen_set_label(l1);
+    tcg_gen_ext32s_tl(t0, t0);
+    gen_store_gpr(t0, a->rt);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+#define DECLEAR_GEN_CL(suffix, arg_type)                                    \
+static bool gen_cl_##suffix(DisasContext *ctx, arg_type * a, bool zero)     \
+{                                                                           \
+    TCGv dest = dest_gpr(ctx, a->rd);                                       \
+    TCGv src = get_gpr(ctx, a->rs, EXT_NONE);                               \
+    if (!zero) {                                                            \
+        tcg_gen_not_tl(dest, src);                                          \
+    }                                                                       \
+    tcg_gen_ext32u_tl(dest, dest);                                          \
+    tcg_gen_clzi_tl(dest, dest, TARGET_LONG_BITS);                          \
+    tcg_gen_subi_tl(dest, dest, TARGET_LONG_BITS - 32);                     \
+    gen_set_gpr(a->rd, dest, EXT_NONE);                                     \
+    return true;                                                            \
+}                                                                           \
+
+DECLEAR_GEN_CL(legacy, arg_r)
+#undef DECLEAR_GEN_CL
+
+#ifdef TARGET_MIPS64
+#define DECLEAR_GEN_DCL(suffix, arg_type)                                   \
+static bool gen_dcl_##suffix(DisasContext *ctx, arg_type * a, bool zero)    \
+{                                                                           \
+    TCGv dest = dest_gpr(ctx, a->rd);                                       \
+    TCGv src = get_gpr(ctx, a->rs, EXT_NONE);                               \
+    if (!zero) {                                                            \
+        tcg_gen_not_tl(dest, src);                                          \
+    }                                                                       \
+    tcg_gen_clzi_i64(dest, dest, 64);                                       \
+    gen_set_gpr(a->rd, dest, EXT_NONE);                                     \
+    return true;                                                            \
+}                                                                           \
+
+DECLEAR_GEN_DCL(legacy, arg_r)
+#undef DECLEAR_GEN_DCL
+#endif
+
+static bool gen_setcond(DisasContext *ctx, arg_r *a, TCGCond cond)
+{
+    TCGv dest = dest_gpr(ctx, a->rd);
+    TCGv src1 = get_gpr(ctx, a->rs, EXT_NONE);
+    TCGv src2 = get_gpr(ctx, a->rt, EXT_NONE);
+
+    tcg_gen_setcond_tl(cond, dest, src1, src2);
+
+    gen_set_gpr(a->rd, dest, EXT_NONE);
+
+    return true;
+}
+
+static bool gen_setcond_imm(DisasContext *ctx, arg_i *a, TCGCond cond)
+{
+    TCGv dest = dest_gpr(ctx, a->rt);
+    TCGv src1 = get_gpr(ctx, a->rs, EXT_NONE);
+
+    tcg_gen_setcondi_tl(cond, dest, src1, a->imm);
+
+    gen_set_gpr(a->rt, dest, EXT_NONE);
+
+    return true;
+}
+
+static bool gen_mult32(DisasContext *ctx, arg_r2_s *a,
+                       void (*func)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32))
+{
+    TCGv src1 = get_gpr(ctx, a->rs, EXT_NONE);
+    TCGv src2 = get_gpr(ctx, a->rt, EXT_NONE);
+    TCGv dst_lo = dest_lo(ctx, 0);
+    TCGv dst_hi = dest_hi(ctx, 0);
+    TCGv_i32 t1 = tcg_temp_new_i32();
+    TCGv_i32 t2 = tcg_temp_new_i32();
+
+    tcg_gen_trunc_tl_i32(t1, src1);
+    tcg_gen_trunc_tl_i32(t2, src2);
+
+    func(t1, t2, t1, t2);
+
+    tcg_gen_ext_i32_tl(dst_lo, t1);
+    tcg_gen_ext_i32_tl(dst_hi, t2);
+
+    gen_set_lo(0, dst_lo, EXT_NONE);
+    gen_set_hi(0, dst_hi, EXT_NONE);
+
+    return true;
+}
+
+#if defined(TARGET_MIPS64)
+static bool gen_mult64(DisasContext *ctx, arg_r2_s *a,
+                       void (*func)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
+{
+    TCGv src1 = get_gpr(ctx, a->rs, EXT_NONE);
+    TCGv src2 = get_gpr(ctx, a->rt, EXT_NONE);
+    TCGv dst_lo = dest_lo(ctx, 0);
+    TCGv dst_hi = dest_hi(ctx, 0);
+
+    func(dst_lo, dst_hi, src1, src2);
+
+    gen_set_lo(0, dst_lo, EXT_NONE);
+    gen_set_hi(0, dst_hi, EXT_NONE);
+
+    return true;
+}
+#endif
+
+static bool gen_div(DisasContext *ctx, arg_r2_s *a, DisasExtend src_ext,
+                    DisasExtend dst_ext)
+{
+    TCGv temp1, temp2, zero, one, mone, min;
+    TCGv src1 = get_gpr(ctx, a->rs, src_ext);
+    TCGv src2 = get_gpr(ctx, a->rt, src_ext);
+    TCGv dst_lo = dest_lo(ctx, 0);
+    TCGv dst_hi = dest_hi(ctx, 0);
+
+    temp1 = tcg_temp_new();
+    temp2 = tcg_temp_new();
+    zero = tcg_constant_tl(0);
+    one = tcg_constant_tl(1);
+    mone = tcg_constant_tl(-1);
+    min = tcg_constant_tl(1ull << (TARGET_LONG_BITS - 1));
+
+    /*
+     * If overflow, set temp2 to 1, else source2.
+     * This produces the required result of min.
+     */
+    tcg_gen_setcond_tl(TCG_COND_EQ, temp1, src1, min);
+    tcg_gen_setcond_tl(TCG_COND_EQ, temp2, src2, mone);
+    tcg_gen_and_tl(temp1, temp1, temp2);
+    tcg_gen_movcond_tl(TCG_COND_NE, temp2, temp1, zero, one, src2);
+
+    /*
+     * If div by zero, set temp1 to -1 and temp2 to 1 to
+     * produce the required result of -1.
+     */
+    tcg_gen_movcond_tl(TCG_COND_EQ, temp1, src2, zero, mone, src1);
+    tcg_gen_movcond_tl(TCG_COND_EQ, temp2, src2, zero, one, src2);
+
+    tcg_gen_div_tl(dst_lo, temp1, temp2);
+    tcg_gen_rem_tl(dst_hi, temp1, temp2);
+
+    tcg_temp_free(temp1);
+    tcg_temp_free(temp2);
+
+    gen_set_lo(0, dst_lo, dst_ext);
+    gen_set_hi(0, dst_hi, dst_ext);
+
+    return true;
+}
+
+static bool gen_divu(DisasContext *ctx, arg_r2_s *a, DisasExtend src_ext,
+                    DisasExtend dst_ext)
+{
+    TCGv temp1, temp2, zero, one, max;
+    TCGv src1 = get_gpr(ctx, a->rs, src_ext);
+    TCGv src2 = get_gpr(ctx, a->rt, src_ext);
+    TCGv dst_lo = dest_lo(ctx, 0);
+    TCGv dst_hi = dest_hi(ctx, 0);
+
+    temp1 = tcg_temp_new();
+    temp2 = tcg_temp_new();
+    zero = tcg_constant_tl(0);
+    one = tcg_constant_tl(1);
+    max = tcg_constant_tl(~0);
+
+    /*
+     * If div by zero, set temp1 to max and temp2 to 1 to
+     * produce the required result of max.
+     */
+    tcg_gen_movcond_tl(TCG_COND_EQ, temp1, src2, zero, max, src1);
+    tcg_gen_movcond_tl(TCG_COND_EQ, temp2, src2, zero, one, src2);
+
+    tcg_gen_divu_tl(dst_lo, temp1, temp2);
+    tcg_gen_remu_tl(dst_hi, temp1, temp2);
+
+    tcg_temp_free(temp1);
+    tcg_temp_free(temp2);
+
+    gen_set_lo(0, dst_lo, dst_ext);
+    gen_set_hi(0, dst_hi, dst_ext);
+
+    return true;
+}
+
+static bool gen_mul_addsub(DisasContext *ctx, arg_r2_s *a, DisasExtend ext,
+                            void (*func)(TCGv_i64, TCGv_i64, TCGv_i64))
+{
+    TCGv src1 = get_gpr(ctx, a->rs, ext);
+    TCGv src2 = get_gpr(ctx, a->rt, ext);
+    TCGv_i64 src3 = get_hilo(ctx, 0);
+    TCGv_i64 dst = dest_hilo(ctx, 0);
+    TCGv_i64 t2 = tcg_temp_new_i64();
+    TCGv_i64 t3 = tcg_temp_new_i64();
+
+    switch (ext) {
+    case EXT_SIGN:
+        tcg_gen_ext_tl_i64(t2, src1);
+        tcg_gen_ext_tl_i64(t3, src2);
+        break;
+    case EXT_ZERO:
+        tcg_gen_extu_tl_i64(t2, src1);
+        tcg_gen_extu_tl_i64(t3, src2);
+        break;
+    default:
+        g_assert_not_reached();
+        break;
+    }
+
+    tcg_gen_mul_i64(dst, t2, t3);
+    tcg_temp_free_i64(t2);
+    tcg_temp_free_i64(t3);
+    func(dst, dst, src3);
+
+    gen_set_hilo(0, dst);
+
+    return true;
+}
+
+TRANS(ADD, gen_add, EXT_SIGN)
+TRANS(ADDU, gen_arith_notrap, EXT_SIGN, tcg_gen_add_tl)
+TRANS_6R(ADDI, gen_add_imm, EXT_SIGN)
+TRANS(ADDIU, gen_arith_imm_notrap, EXT_SIGN, tcg_gen_addi_tl)
+TRANS(SUB, gen_sub, EXT_SIGN)
+TRANS(SUBU, gen_arith_notrap, EXT_SIGN, tcg_gen_sub_tl)
+TRANS_6R(CLO, gen_cl_legacy, false)
+TRANS_6R(CLZ, gen_cl_legacy, true)
+TRANS(SLT, gen_setcond, TCG_COND_LT)
+TRANS(SLTU, gen_setcond, TCG_COND_LTU)
+TRANS(SLTI, gen_setcond_imm, TCG_COND_LT)
+TRANS(SLTIU, gen_setcond_imm, TCG_COND_LTU)
+TRANS_6R(MUL, gen_arith_notrap, EXT_SIGN, tcg_gen_mul_tl)
+TRANS_6R(MULT, gen_mult32, tcg_gen_muls2_i32)
+TRANS_6R(MULTU, gen_mult32, tcg_gen_mulu2_i32)
+TRANS_6R(DIV, gen_div, EXT_SIGN, EXT_SIGN)
+TRANS_6R(DIVU, gen_divu, EXT_ZERO, EXT_SIGN)
+TRANS_6R(MADD, gen_mul_addsub, EXT_SIGN, tcg_gen_add_i64)
+TRANS_6R(MADDU, gen_mul_addsub, EXT_ZERO, tcg_gen_add_i64)
+TRANS_6R(MSUB, gen_mul_addsub, EXT_SIGN, tcg_gen_sub_i64)
+TRANS_6R(MSUBU, gen_mul_addsub, EXT_ZERO, tcg_gen_sub_i64)
+
+TRANS64(DADD, gen_add, EXT_NONE)
+TRANS64(DADDU, gen_arith_notrap, EXT_NONE, tcg_gen_add_tl)
+TRANS64_6R(DADDI, gen_add_imm, EXT_NONE)
+TRANS64(DADDIU, gen_arith_imm_notrap, EXT_NONE, tcg_gen_addi_tl)
+TRANS64(DSUB, gen_sub, EXT_NONE)
+TRANS64(DSUBU, gen_arith_notrap, EXT_NONE, tcg_gen_sub_tl)
+TRANS64_6R(DCLO, gen_dcl_legacy, false)
+TRANS64_6R(DCLZ, gen_dcl_legacy, true)
+TRANS64_6R(DMULT, gen_mult64, tcg_gen_muls2_i64)
+TRANS64_6R(DMULTU, gen_mult64, tcg_gen_mulu2_i64)
+TRANS64_6R(DDIV, gen_div, EXT_NONE, EXT_NONE)
+TRANS64_6R(DDIVU, gen_divu, EXT_NONE, EXT_NONE)
diff --git a/target/mips/tcg/legacy.decode b/target/mips/tcg/legacy.decode
new file mode 100644
index 0000000000..d535fbe31b
--- /dev/null
+++ b/target/mips/tcg/legacy.decode
@@ -0,0 +1,62 @@
+# MIPS I to MIPS Release 5 instructions
+#
+# Copyright (C) 2022 Jiaxun Yang
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+
+
+# Fields:
+%rd       11:5
+%rs       21:5
+%rt       16:5
+
+%imms16   0:s16
+
+# Argument sets:
+&empty
+&r      rd rs rt
+&r2_s   rs rt
+&i      rt rs imm
+
+# Formats:
+@r             ................................     &r  %rd %rs %rt
+@r2_s          ................................     &r2_s %rs %rt
+@i             ................................     &i   %rt %rs imm=%imms16
+
+# Base arithmetic instructions
+ADD            000000 ...............00000100000       @r
+ADDI           001000 ..........................       @i # 6R
+ADDIU          001001 ..........................       @i
+ADDU           000000 ...............00000100001       @r
+CLO            011100 ...............00000100001       @r # 6Rm
+CLZ            011100 ...............00000100000       @r # 6Rm
+DIV            000000 ..........0000000000011010       @r2_s # 6R
+DIVU           000000 ..........0000000000011011       @r2_s # 6R
+MADD           011100 ..........0000000000000000       @r2_s # 6R
+MADDU          011100 ..........0000000000000001       @r2_s # 6R
+MSUB           011100 ..........0000000000000100       @r2_s # 6R
+MSUBU          011100 ..........0000000000000101       @r2_s # 6R
+MUL            011100 ...............00000000010       @r    # 6R
+MULT           000000 ..........0000000000011000       @r2_s # 6R
+MULTU          000000 ..........0000000000011001       @r2_s # 6R
+SLT            000000 ...............00000101010       @r
+SLTI           001010 ..........................       @i
+SLTIU          001011 ..........................       @i
+SLTU           000000 ...............00000101011       @r
+SUB            000000 ...............00000100010       @r
+SUBU           000000 ...............00000100011       @r
+
+
+DADD           000000 ...............00000101100       @r
+DADDI          011000 ..........................       @i # 6R
+DADDIU         011001 ..........................       @i
+DADDU          000000 ...............00000101101       @r
+DCLO           011100 ...............00000100101       @r # 6Rm
+DCLZ           011100 ...............00000100100       @r # 6Rm
+DDIV           000000 ..........0000000000011110       @r2_s # 6R
+DDIVU          000000 ..........0000000000011111       @r2_s # 6R
+DSUB           000000 ...............00000101110       @r
+DSUBU          000000 ...............00000101111       @r
+DMULT          000000 ..........0000000000011100       @r2_s # 6R
+DMULTU         000000 ..........0000000000011101       @r2_s  # 6R
diff --git a/target/mips/tcg/meson.build b/target/mips/tcg/meson.build
index 7ee969ec8f..7a27fe93e0 100644
--- a/target/mips/tcg/meson.build
+++ b/target/mips/tcg/meson.build
@@ -1,4 +1,5 @@
 gen = [
+  decodetree.process('legacy.decode', extra_args: ['--static-decode=decode_isa_legacy']),
   decodetree.process('rel6.decode', extra_args: ['--decode=decode_isa_rel6']),
   decodetree.process('msa.decode', extra_args: '--decode=decode_ase_msa'),
   decodetree.process('tx79.decode', extra_args: '--static-decode=decode_tx79'),
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index b5d595ef34..bcb267e6bd 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -38,6 +38,9 @@
 #include "fpu_helper.h"
 #include "translate.h"
 
+/* Include the generated ISA decoders */
+#include "decode-legacy.c.inc"
+
 /*
  * Many sysemu-only helpers are not reachable for user-only.
  * Define stub generators here, so that we need not either sprinkle
@@ -1196,16 +1199,6 @@ enum {
     MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
 };
 
-/*
- * If an operation is being performed on less than TARGET_LONG_BITS,
- * it may require the inputs to be sign- or zero-extended; which will
- * depend on the exact operation being performed.
- */
-typedef enum {
-    EXT_NONE,
-    EXT_SIGN,
-    EXT_ZERO
-} DisasExtend;
 
 /* global register indices */
 TCGv cpu_gpr[32], cpu_PC;
@@ -12261,6 +12254,9 @@ static void gen_sync(int stype)
     tcg_gen_mb(tcg_mo);
 }
 
+/* ISA base */
+#include "insn_trans/trans_arith.c.inc"
+
 /* ISA extensions (ASEs) */
 
 /* MIPS16 extension to MIPS32 */
@@ -16090,6 +16086,10 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
         return;
     }
 
+    if (decode_isa_legacy(ctx, ctx->opcode)) {
+        return;
+    }
+
     if (decode_opc_legacy(env, ctx)) {
         return;
     }
-- 
2.34.1



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

* [RFC PATCH 3/3] tests/tcg/mips: Add mips32 arithmatic instruction test cases
  2022-09-21 12:41 [RFC PATCH 0/3] MIPS decodetree conversion attempt Jiaxun Yang
  2022-09-21 12:41 ` [RFC PATCH 1/3] target/mips: Introduce register access helper functions Jiaxun Yang
  2022-09-21 12:41 ` [RFC PATCH 2/3] target/mips: Convert legacy arithmatic instructions to decodetree Jiaxun Yang
@ 2022-09-21 12:41 ` Jiaxun Yang
  2022-09-26 14:44 ` [RFC PATCH 0/3] MIPS decodetree conversion attempt Jiaxun Yang
  3 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2022-09-21 12:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: f4bug, richard.henderson, Jiaxun Yang

Those cases are delivered from MIPS internal architecture validation
tools.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 tests/tcg/mips/include/test_utils_32.h        |  75 +++++++++++
 .../tcg/mips/user/isa/mips32/arithmatic/add.c |  99 ++++++++++++++
 .../mips/user/isa/mips32/arithmatic/addi.c    |  70 ++++++++++
 .../mips/user/isa/mips32/arithmatic/addiu.c   |  90 +++++++++++++
 .../mips/user/isa/mips32/arithmatic/addu.c    | 125 ++++++++++++++++++
 .../tcg/mips/user/isa/mips32/arithmatic/div.c |  81 ++++++++++++
 .../mips/user/isa/mips32/arithmatic/divu.c    |  78 +++++++++++
 .../mips/user/isa/mips32/arithmatic/madd.c    |  79 +++++++++++
 .../mips/user/isa/mips32/arithmatic/maddu.c   |  78 +++++++++++
 .../mips/user/isa/mips32/arithmatic/msub.c    |  78 +++++++++++
 .../mips/user/isa/mips32/arithmatic/msubu.c   |  78 +++++++++++
 .../tcg/mips/user/isa/mips32/arithmatic/mul.c |  78 +++++++++++
 .../mips/user/isa/mips32/arithmatic/mult.c    |  78 +++++++++++
 .../mips/user/isa/mips32/arithmatic/multu.c   |  78 +++++++++++
 .../tcg/mips/user/isa/mips32/arithmatic/slt.c |  61 +++++++++
 .../mips/user/isa/mips32/arithmatic/slti.c    |  48 +++++++
 .../mips/user/isa/mips32/arithmatic/sltiu.c   |  48 +++++++
 .../mips/user/isa/mips32/arithmatic/sltu.c    |  61 +++++++++
 .../tcg/mips/user/isa/mips32/arithmatic/sub.c | 104 +++++++++++++++
 .../mips/user/isa/mips32/arithmatic/subu.c    | 108 +++++++++++++++
 20 files changed, 1595 insertions(+)
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/add.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addi.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/div.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/divu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/madd.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/maddu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msubu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mul.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mult.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/multu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slt.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slti.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/subu.c

diff --git a/tests/tcg/mips/include/test_utils_32.h b/tests/tcg/mips/include/test_utils_32.h
index c33990c0c5..00480e3283 100644
--- a/tests/tcg/mips/include/test_utils_32.h
+++ b/tests/tcg/mips/include/test_utils_32.h
@@ -29,6 +29,81 @@
 
 #define PRINT_RESULTS 0
 
+#define DO_MIPS32_r(mnemonic, id, input1, input2, expect)              \
+{                                                                      \
+    uint32_t output;                                                   \
+    uint32_t expect_val = expect;                                      \
+    __asm__ volatile (                                                 \
+      "li $t1, " #input1 "\n\t"                                        \
+      "li $t2, " #input2 "\n\t"                                        \
+      #mnemonic " $t0, $t1, $t2\n\t"                                   \
+      "sw $t0, 0(%0)\n\t"                                              \
+      :                                                                \
+      : "r" (&output)                                                  \
+      : "t0", "t1", "t2", "memory"                                     \
+    );                                                                 \
+    check_single_insn_32(id, &pass_count, &fail_count, 1, &expect_val, &output); \
+}
+
+#define DO_MIPS32_i(mnemonic, id, imm, input1, expect)                 \
+{                                                                      \
+    uint32_t output;                                                   \
+    uint32_t expect_val = expect;                                      \
+    __asm__ volatile (                                                 \
+      "li $t1, " #input1 "\n\t"                                        \
+      #mnemonic " $t0, $t1, " #imm "\n\t"                              \
+      "sw $t0, 0(%0)\n\t"                                              \
+      :                                                                \
+      : "r" (&output)                                                  \
+      : "t0", "t1", "memory"                                           \
+    );                                                                 \
+    check_single_insn_32(id, &pass_count, &fail_count, 1, &expect_val, &output); \
+}
+
+#define DO_MIPS32_r2_s(mnemonic, id, hi, lo, input1, input2, expect_hi, expect_lo) \
+{                                                                      \
+    uint32_t output[2];                                                \
+    uint32_t expect_val[2] = {expect_lo, expect_hi};                   \
+    __asm__ volatile (                                                 \
+      ".set noreorder \n\t"                                            \
+      "li $t0, " #hi "\n\t"                                            \
+      "mthi $t0       \n\t"                                            \
+      "li $t0, " #lo "\n\t"                                            \
+      "mtlo $t0       \n\t"                                            \
+      "li $t0, " #input1 "\n\t"                                        \
+      "li $t1, " #input2 "\n\t"                                        \
+      #mnemonic " $t0, $t1 \n\t"                                       \
+      "mfhi $t0       \n\t"                                            \
+      "sw $t0, 4(%0)\n\t"                                              \
+      "mflo $t0       \n\t"                                            \
+      "sw $t0, 0(%0)\n\t"                                              \
+      ".set reorder \n\t"                                              \
+      :                                                                \
+      : "r" (&output)                                                  \
+      : "t0", "t1", "hi", "lo", "memory"                              \
+    );                                                                 \
+    check_single_insn_32(id, &pass_count, &fail_count, 2, expect_val, output); \
+}
+
+static inline void check_single_insn_32(int id, int *pass, int *fail, int cnt,
+                                        uint32_t *expect, uint32_t *actual)
+{
+    int i;
+
+    if (memcmp(expect, actual, 4 * cnt) == 0) {
+        (*pass)++;
+        printf("Case %d pass:\n", id);
+        for (i = 0; i < cnt; i++) {
+            printf("    [%d]: actual: 0x%08x, expect: 0x%08x\n", i, actual[i], expect[i]);
+        }
+    } else {
+        (*fail)++;
+        printf("Case %d fail:\n", id);
+        for (i = 0; i < cnt; i++) {
+            printf("    [%d]: actual: 0x%08x, expect: 0x%08x\n", i, actual[i], expect[i]);
+        }
+    }
+}
 
 static inline int32_t check_results_32(const char *instruction_name,
                                        const uint32_t test_count,
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/add.c b/tests/tcg/mips/user/isa/mips32/arithmatic/add.c
new file mode 100644
index 0000000000..2e1d380c90
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/add.c
@@ -0,0 +1,99 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r(add, 0, 0x00000000, 0x00000000, 0x00000000);
+    DO_MIPS32_r(add, 1, 0x00000001, 0x00000001, 0x00000002);
+    DO_MIPS32_r(add, 2, 0x00000002, 0x00000003, 0x00000005);
+    DO_MIPS32_r(add, 3, 0x00000004, 0x00000007, 0x0000000B);
+    DO_MIPS32_r(add, 4, 0x00000008, 0x0000000F, 0x00000017);
+    DO_MIPS32_r(add, 5, 0x00000010, 0x0000001F, 0x0000002F);
+    DO_MIPS32_r(add, 6, 0x00000020, 0x0000003F, 0x0000005F);
+    DO_MIPS32_r(add, 7, 0x00000040, 0x0000007F, 0x000000BF);
+    DO_MIPS32_r(add, 8, 0x00000080, 0x000000FF, 0x0000017F);
+    DO_MIPS32_r(add, 9, 0x00000100, 0x000001FF, 0x000002FF);
+    DO_MIPS32_r(add, 10, 0x00000200, 0x000003FF, 0x000005FF);
+    DO_MIPS32_r(add, 11, 0x00000400, 0x000007FF, 0x00000BFF);
+    DO_MIPS32_r(add, 12, 0x00000800, 0x00000FFF, 0x000017FF);
+    DO_MIPS32_r(add, 13, 0x00001000, 0x00001FFF, 0x00002FFF);
+    DO_MIPS32_r(add, 14, 0x00002000, 0x00003FFF, 0x00005FFF);
+    DO_MIPS32_r(add, 15, 0x00004000, 0x00007FFF, 0x0000BFFF);
+    DO_MIPS32_r(add, 16, 0x00008000, 0x0000FFFF, 0x00017FFF);
+    DO_MIPS32_r(add, 17, 0x00010000, 0x0001FFFF, 0x0002FFFF);
+    DO_MIPS32_r(add, 18, 0x00020000, 0x0003FFFF, 0x0005FFFF);
+    DO_MIPS32_r(add, 19, 0x00040000, 0x0007FFFF, 0x000BFFFF);
+    DO_MIPS32_r(add, 20, 0x00080000, 0x000FFFFF, 0x0017FFFF);
+    DO_MIPS32_r(add, 21, 0x00100000, 0x001FFFFF, 0x002FFFFF);
+    DO_MIPS32_r(add, 22, 0x00200000, 0x003FFFFF, 0x005FFFFF);
+    DO_MIPS32_r(add, 23, 0x00400000, 0x007FFFFF, 0x00BFFFFF);
+    DO_MIPS32_r(add, 24, 0x00800000, 0x00FFFFFF, 0x017FFFFF);
+    DO_MIPS32_r(add, 25, 0x01000000, 0x01FFFFFF, 0x02FFFFFF);
+    DO_MIPS32_r(add, 26, 0x02000000, 0x03FFFFFF, 0x05FFFFFF);
+    DO_MIPS32_r(add, 27, 0x04000000, 0x07FFFFFF, 0x0BFFFFFF);
+    DO_MIPS32_r(add, 28, 0x08000000, 0x0FFFFFFF, 0x17FFFFFF);
+    DO_MIPS32_r(add, 29, 0x10000000, 0x1FFFFFFF, 0x2FFFFFFF);
+    DO_MIPS32_r(add, 30, 0x20000000, 0x3FFFFFFF, 0x5FFFFFFF);
+    DO_MIPS32_r(add, 31, 0x00000000, 0x00000001, 0x00000001);
+    DO_MIPS32_r(add, 32, 0x80000001, 0xFFFFFFFF, 0x80000000);
+    DO_MIPS32_r(add, 33, 0xC0000003, 0x7FFFFFFD, 0x40000000);
+    DO_MIPS32_r(add, 34, 0xE0000007, 0x3FFFFFF9, 0x20000000);
+    DO_MIPS32_r(add, 35, 0xF000000F, 0x1FFFFFF1, 0x10000000);
+    DO_MIPS32_r(add, 36, 0xF800001F, 0x0FFFFFE1, 0x08000000);
+    DO_MIPS32_r(add, 37, 0xFC00003F, 0x07FFFFC1, 0x04000000);
+    DO_MIPS32_r(add, 38, 0xFE00007F, 0x03FFFF81, 0x02000000);
+    DO_MIPS32_r(add, 39, 0xFF0000FF, 0x01FFFF01, 0x01000000);
+    DO_MIPS32_r(add, 40, 0xFF8001FF, 0x00FFFE01, 0x00800000);
+    DO_MIPS32_r(add, 41, 0xFFC003FF, 0x007FFC01, 0x00400000);
+    DO_MIPS32_r(add, 42, 0xFFE007FF, 0x003FF801, 0x00200000);
+    DO_MIPS32_r(add, 43, 0xFFF00FFF, 0x001FF001, 0x00100000);
+    DO_MIPS32_r(add, 44, 0xFFF81FFF, 0x000FE001, 0x00080000);
+    DO_MIPS32_r(add, 45, 0xFFFC3FFF, 0x0007C001, 0x00040000);
+    DO_MIPS32_r(add, 46, 0xFFFE7FFF, 0x00038001, 0x00020000);
+    DO_MIPS32_r(add, 47, 0xFFFFFFFF, 0x00010001, 0x00010000);
+    DO_MIPS32_r(add, 48, 0xFFFFFFFF, 0x00018001, 0x00018000);
+    DO_MIPS32_r(add, 49, 0xFFFE7FFF, 0x00024001, 0x0000C000);
+    DO_MIPS32_r(add, 50, 0xFFFC3FFF, 0x00042001, 0x00006000);
+    DO_MIPS32_r(add, 51, 0xFFF81FFF, 0x00081001, 0x00003000);
+    DO_MIPS32_r(add, 52, 0xFFF00FFF, 0x00100801, 0x00001800);
+    DO_MIPS32_r(add, 53, 0xFFE007FF, 0x00200401, 0x00000C00);
+    DO_MIPS32_r(add, 54, 0xFFC003FF, 0x00400201, 0x00000600);
+    DO_MIPS32_r(add, 55, 0xFF8001FF, 0x00800101, 0x00000300);
+    DO_MIPS32_r(add, 56, 0xFF0000FF, 0x01000081, 0x00000180);
+    DO_MIPS32_r(add, 57, 0xFE00007F, 0x02000041, 0x000000C0);
+    DO_MIPS32_r(add, 58, 0xFC00003F, 0x04000021, 0x00000060);
+    DO_MIPS32_r(add, 59, 0xF800001F, 0x08000011, 0x00000030);
+    DO_MIPS32_r(add, 60, 0xF000000F, 0x10000009, 0x00000018);
+    DO_MIPS32_r(add, 61, 0xE0000007, 0x20000005, 0x0000000C);
+    DO_MIPS32_r(add, 62, 0xC0000003, 0x40000003, 0x00000006);
+    DO_MIPS32_r(add, 63, 0x00000000, 0x55555555, 0x55555555);
+    DO_MIPS32_r(add, 64, 0x15555555, 0x55555555, 0x6AAAAAAA);
+    DO_MIPS32_r(add, 65, 0xAAAAAAAA, 0x55555555, 0xFFFFFFFF);
+    DO_MIPS32_r(add, 66, 0xFFFFFFFF, 0x55555555, 0x55555554);
+    DO_MIPS32_r(add, 67, 0xAAAAAAAA, 0x00000000, 0xAAAAAAAA);
+    DO_MIPS32_r(add, 68, 0xAAAAAAAA, 0x55555555, 0xFFFFFFFF);
+    DO_MIPS32_r(add, 69, 0xAAAAAAAA, 0x2AAAAAAA, 0xD5555554);
+    DO_MIPS32_r(add, 70, 0xAAAAAAAA, 0xFFFFFFFF, 0xAAAAAAA9);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/addi.c b/tests/tcg/mips/user/isa/mips32/arithmatic/addi.c
new file mode 100644
index 0000000000..c032e4d9e5
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/addi.c
@@ -0,0 +1,70 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_i(addi, 0, 0x0000, 0x00000000, 0x00000000);
+    DO_MIPS32_i(addi, 1, 0x0001, 0x00000001, 0x00000002);
+    DO_MIPS32_i(addi, 2, 0x0003, 0x00000002, 0x00000005);
+    DO_MIPS32_i(addi, 3, 0x0007, 0x00000004, 0x0000000B);
+    DO_MIPS32_i(addi, 4, 0x000F, 0x00000008, 0x00000017);
+    DO_MIPS32_i(addi, 5, 0x001F, 0x00000010, 0x0000002F);
+    DO_MIPS32_i(addi, 6, 0x003F, 0x00000020, 0x0000005F);
+    DO_MIPS32_i(addi, 7, 0x007F, 0x00000040, 0x000000BF);
+    DO_MIPS32_i(addi, 8, 0x00FF, 0x00000080, 0x0000017F);
+    DO_MIPS32_i(addi, 9, 0x01FF, 0x00000100, 0x000002FF);
+    DO_MIPS32_i(addi, 10, 0x03FF, 0x00000200, 0x000005FF);
+    DO_MIPS32_i(addi, 11, 0x07FF, 0x00000400, 0x00000BFF);
+    DO_MIPS32_i(addi, 12, 0x0FFF, 0x00000800, 0x000017FF);
+    DO_MIPS32_i(addi, 13, 0x1FFF, 0x00001000, 0x00002FFF);
+    DO_MIPS32_i(addi, 14, 0x3FFF, 0x00002000, 0x00005FFF);
+    DO_MIPS32_i(addi, 15, 0x7FFF, 0x00004000, 0x0000BFFF);
+    DO_MIPS32_i(addi, 16, 0xFFFF, 0x00008000, 0x00007FFF);
+    DO_MIPS32_i(addi, 17, 0x0001, 0x00000000, 0x00000001);
+    DO_MIPS32_i(addi, 18, 0xFFFF, 0x80000001, 0x80000000);
+    DO_MIPS32_i(addi, 19, 0xFFFD, 0xC0000003, 0xC0000000);
+    DO_MIPS32_i(addi, 20, 0xFFF9, 0xE0000007, 0xE0000000);
+    DO_MIPS32_i(addi, 21, 0xFFF1, 0xF000000F, 0xF0000000);
+    DO_MIPS32_i(addi, 22, 0xFFE1, 0xF800001F, 0xF8000000);
+    DO_MIPS32_i(addi, 23, 0xFFC1, 0xFC00003F, 0xFC000000);
+    DO_MIPS32_i(addi, 24, 0xFF81, 0xFE00007F, 0xFE000000);
+    DO_MIPS32_i(addi, 25, 0xFF01, 0xFF0000FF, 0xFF000000);
+    DO_MIPS32_i(addi, 26, 0xFE01, 0xFF8001FF, 0xFF800000);
+    DO_MIPS32_i(addi, 27, 0xFC01, 0xFFC003FF, 0xFFC00000);
+    DO_MIPS32_i(addi, 28, 0xF801, 0xFFE007FF, 0xFFE00000);
+    DO_MIPS32_i(addi, 29, 0xF001, 0xFFF00FFF, 0xFFF00000);
+    DO_MIPS32_i(addi, 30, 0xE001, 0xFFF81FFF, 0xFFF80000);
+    DO_MIPS32_i(addi, 31, 0xC001, 0xFFFC3FFF, 0xFFFC0000);
+    DO_MIPS32_i(addi, 32, 0x8001, 0xFFFE7FFF, 0xFFFE0000);
+    DO_MIPS32_i(addi, 33, 0x0001, 0xFFFFFFFF, 0x00000000);
+    DO_MIPS32_i(addi, 34, 0x5555, 0x00000000, 0x00005555);
+    DO_MIPS32_i(addi, 35, 0x5555, 0x55555555, 0x5555AAAA);
+    DO_MIPS32_i(addi, 36, 0x5555, 0xAAAAAAAA, 0xAAAAFFFF);
+    DO_MIPS32_i(addi, 37, 0x5555, 0xFFFFFFFF, 0x00005554);
+    DO_MIPS32_i(addi, 38, 0x0000, 0xAAAAAAAA, 0xAAAAAAAA);
+    DO_MIPS32_i(addi, 39, 0x5555, 0xAAAAAAAA, 0xAAAAFFFF);
+    DO_MIPS32_i(addi, 40, 0xAAAA, 0xAAAAAAAA, 0xAAAA5554);
+    DO_MIPS32_i(addi, 41, 0xFFFF, 0xAAAAAAAA, 0xAAAAAAA9);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/addiu.c b/tests/tcg/mips/user/isa/mips32/arithmatic/addiu.c
new file mode 100644
index 0000000000..cdc2ebc932
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/addiu.c
@@ -0,0 +1,90 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_i(addiu, 0, 0x0000, 0x00000000, 0x00000000);
+    DO_MIPS32_i(addiu, 1, 0x0001, 0x00000001, 0x00000002);
+    DO_MIPS32_i(addiu, 2, 0x0003, 0x00000002, 0x00000005);
+    DO_MIPS32_i(addiu, 3, 0x0007, 0x00000004, 0x0000000B);
+    DO_MIPS32_i(addiu, 4, 0x000F, 0x00000008, 0x00000017);
+    DO_MIPS32_i(addiu, 5, 0x001F, 0x00000010, 0x0000002F);
+    DO_MIPS32_i(addiu, 6, 0x003F, 0x00000020, 0x0000005F);
+    DO_MIPS32_i(addiu, 7, 0x007F, 0x00000040, 0x000000BF);
+    DO_MIPS32_i(addiu, 8, 0x00FF, 0x00000080, 0x0000017F);
+    DO_MIPS32_i(addiu, 9, 0x01FF, 0x00000100, 0x000002FF);
+    DO_MIPS32_i(addiu, 10, 0x03FF, 0x00000200, 0x000005FF);
+    DO_MIPS32_i(addiu, 11, 0x07FF, 0x00000400, 0x00000BFF);
+    DO_MIPS32_i(addiu, 12, 0x0FFF, 0x00000800, 0x000017FF);
+    DO_MIPS32_i(addiu, 13, 0x1FFF, 0x00001000, 0x00002FFF);
+    DO_MIPS32_i(addiu, 14, 0x3FFF, 0x00002000, 0x00005FFF);
+    DO_MIPS32_i(addiu, 15, 0x7FFF, 0x00004000, 0x0000BFFF);
+    DO_MIPS32_i(addiu, 16, -1, 0x00008000, 0x00007FFF);
+    DO_MIPS32_i(addiu, 17, 0x0001, 0x00000000, 0x00000001);
+    DO_MIPS32_i(addiu, 18, -1, 0x80000001, 0x80000000);
+    DO_MIPS32_i(addiu, 19, -3, 0xC0000003, 0xC0000000);
+    DO_MIPS32_i(addiu, 20, -7, 0xE0000007, 0xE0000000);
+    DO_MIPS32_i(addiu, 21, -15, 0xF000000F, 0xF0000000);
+    DO_MIPS32_i(addiu, 22, -31, 0xF800001F, 0xF8000000);
+    DO_MIPS32_i(addiu, 23, -63, 0xFC00003F, 0xFC000000);
+    DO_MIPS32_i(addiu, 24, -127, 0xFE00007F, 0xFE000000);
+    DO_MIPS32_i(addiu, 25, -255, 0xFF0000FF, 0xFF000000);
+    DO_MIPS32_i(addiu, 26, -511, 0xFF8001FF, 0xFF800000);
+    DO_MIPS32_i(addiu, 27, -1023, 0xFFC003FF, 0xFFC00000);
+    DO_MIPS32_i(addiu, 28, -2047, 0xFFE007FF, 0xFFE00000);
+    DO_MIPS32_i(addiu, 29, -4095, 0xFFF00FFF, 0xFFF00000);
+    DO_MIPS32_i(addiu, 30, -8191, 0xFFF81FFF, 0xFFF80000);
+    DO_MIPS32_i(addiu, 31, 0xC001, 0xFFFC3FFF, 0xFFFC0000);
+    DO_MIPS32_i(addiu, 32, 0x8001, 0xFFFE7FFF, 0xFFFE0000);
+    DO_MIPS32_i(addiu, 33, 0x0001, 0xFFFFFFFF, 0x00000000);
+    DO_MIPS32_i(addiu, 34, 0x5555, 0x00000000, 0x00005555);
+    DO_MIPS32_i(addiu, 35, 0x5555, 0x55555555, 0x5555AAAA);
+    DO_MIPS32_i(addiu, 36, 0x5555, 0xAAAAAAAA, 0xAAAAFFFF);
+    DO_MIPS32_i(addiu, 37, 0x5555, 0xFFFFFFFF, 0x00005554);
+    DO_MIPS32_i(addiu, 38, 0x0000, 0xAAAAAAAA, 0xAAAAAAAA);
+    DO_MIPS32_i(addiu, 39, 0x5555, 0xAAAAAAAA, 0xAAAAFFFF);
+    DO_MIPS32_i(addiu, 40, 0xAAAA, 0xAAAAAAAA, 0xAAAA5554);
+    DO_MIPS32_i(addiu, 41, -1, 0xAAAAAAAA, 0xAAAAAAA9);
+    DO_MIPS32_i(addiu, 42, 0x0001, 0x7FFFFFFF, 0x80000000);
+    DO_MIPS32_i(addiu, 43, 0x7FFF, 0x7FFFFFFF, 0x80007FFE);
+    DO_MIPS32_i(addiu, 44, -1, 0x80000000, 0x7FFFFFFF);
+    DO_MIPS32_i(addiu, 45, 0x8000, 0x80000000, 0x7FFF8000);
+    DO_MIPS32_i(addiu, 46, 0x555F, 0x7FFFAAAA, 0x80000009);
+    DO_MIPS32_i(addiu, 47, 0xAAAA, 0x7FFF5555, 0x7FFEFFFF);
+    DO_MIPS32_i(addiu, 48, 0x0002, 0x7FFFFFFF, 0x80000001);
+    DO_MIPS32_i(addiu, 49, 0x0004, 0x7FFFFFFF, 0x80000003);
+    DO_MIPS32_i(addiu, 50, 0x0008, 0x7FFFFFFF, 0x80000007);
+    DO_MIPS32_i(addiu, 51, 0x0010, 0x7FFFFFFF, 0x8000000F);
+    DO_MIPS32_i(addiu, 52, 0x0020, 0x7FFFFFFF, 0x8000001F);
+    DO_MIPS32_i(addiu, 53, 0x0040, 0x7FFFFFFF, 0x8000003F);
+    DO_MIPS32_i(addiu, 54, 0x0080, 0x7FFFFFFF, 0x8000007F);
+    DO_MIPS32_i(addiu, 55, 0x0100, 0x7FFFFFFF, 0x800000FF);
+    DO_MIPS32_i(addiu, 56, 0x0200, 0x7FFFFFFF, 0x800001FF);
+    DO_MIPS32_i(addiu, 57, 0x0400, 0x7FFFFFFF, 0x800003FF);
+    DO_MIPS32_i(addiu, 58, 0x0800, 0x7FFFFFFF, 0x800007FF);
+    DO_MIPS32_i(addiu, 59, 0x1000, 0x7FFFFFFF, 0x80000FFF);
+    DO_MIPS32_i(addiu, 60, 0x2000, 0x7FFFFFFF, 0x80001FFF);
+    DO_MIPS32_i(addiu, 61, 0x4000, 0x7FFFFFFF, 0x80003FFF);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/addu.c b/tests/tcg/mips/user/isa/mips32/arithmatic/addu.c
new file mode 100644
index 0000000000..062999edd6
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/addu.c
@@ -0,0 +1,125 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r(addu, 0, 0x00000000, 0x00000000, 0x00000000);
+    DO_MIPS32_r(addu, 1, 0x00000001, 0x00000001, 0x00000002);
+    DO_MIPS32_r(addu, 2, 0x00000002, 0x00000003, 0x00000005);
+    DO_MIPS32_r(addu, 3, 0x00000004, 0x00000007, 0x0000000B);
+    DO_MIPS32_r(addu, 4, 0x00000008, 0x0000000F, 0x00000017);
+    DO_MIPS32_r(addu, 5, 0x00000010, 0x0000001F, 0x0000002F);
+    DO_MIPS32_r(addu, 6, 0x00000020, 0x0000003F, 0x0000005F);
+    DO_MIPS32_r(addu, 7, 0x00000040, 0x0000007F, 0x000000BF);
+    DO_MIPS32_r(addu, 8, 0x00000080, 0x000000FF, 0x0000017F);
+    DO_MIPS32_r(addu, 9, 0x00000100, 0x000001FF, 0x000002FF);
+    DO_MIPS32_r(addu, 10, 0x00000200, 0x000003FF, 0x000005FF);
+    DO_MIPS32_r(addu, 11, 0x00000400, 0x000007FF, 0x00000BFF);
+    DO_MIPS32_r(addu, 12, 0x00000800, 0x00000FFF, 0x000017FF);
+    DO_MIPS32_r(addu, 13, 0x00001000, 0x00001FFF, 0x00002FFF);
+    DO_MIPS32_r(addu, 14, 0x00002000, 0x00003FFF, 0x00005FFF);
+    DO_MIPS32_r(addu, 15, 0x00004000, 0x00007FFF, 0x0000BFFF);
+    DO_MIPS32_r(addu, 16, 0x00008000, 0x0000FFFF, 0x00017FFF);
+    DO_MIPS32_r(addu, 17, 0x00010000, 0x0001FFFF, 0x0002FFFF);
+    DO_MIPS32_r(addu, 18, 0x00020000, 0x0003FFFF, 0x0005FFFF);
+    DO_MIPS32_r(addu, 19, 0x00040000, 0x0007FFFF, 0x000BFFFF);
+    DO_MIPS32_r(addu, 20, 0x00080000, 0x000FFFFF, 0x0017FFFF);
+    DO_MIPS32_r(addu, 21, 0x00100000, 0x001FFFFF, 0x002FFFFF);
+    DO_MIPS32_r(addu, 22, 0x00200000, 0x003FFFFF, 0x005FFFFF);
+    DO_MIPS32_r(addu, 23, 0x00400000, 0x007FFFFF, 0x00BFFFFF);
+    DO_MIPS32_r(addu, 24, 0x00800000, 0x00FFFFFF, 0x017FFFFF);
+    DO_MIPS32_r(addu, 25, 0x01000000, 0x01FFFFFF, 0x02FFFFFF);
+    DO_MIPS32_r(addu, 26, 0x02000000, 0x03FFFFFF, 0x05FFFFFF);
+    DO_MIPS32_r(addu, 27, 0x04000000, 0x07FFFFFF, 0x0BFFFFFF);
+    DO_MIPS32_r(addu, 28, 0x08000000, 0x0FFFFFFF, 0x17FFFFFF);
+    DO_MIPS32_r(addu, 29, 0x10000000, 0x1FFFFFFF, 0x2FFFFFFF);
+    DO_MIPS32_r(addu, 30, 0x20000000, 0x3FFFFFFF, 0x5FFFFFFF);
+    DO_MIPS32_r(addu, 31, 0x40000000, 0x7FFFFFFF, 0xBFFFFFFF);
+    DO_MIPS32_r(addu, 32, 0x80000000, 0xFFFFFFFF, 0x7FFFFFFF);
+    DO_MIPS32_r(addu, 33, 0x00000000, 0x00000001, 0x00000001);
+    DO_MIPS32_r(addu, 34, 0x80000001, 0xFFFFFFFF, 0x80000000);
+    DO_MIPS32_r(addu, 35, 0xC0000003, 0x7FFFFFFD, 0x40000000);
+    DO_MIPS32_r(addu, 36, 0xE0000007, 0x3FFFFFF9, 0x20000000);
+    DO_MIPS32_r(addu, 37, 0xF000000F, 0x1FFFFFF1, 0x10000000);
+    DO_MIPS32_r(addu, 38, 0xF800001F, 0x0FFFFFE1, 0x08000000);
+    DO_MIPS32_r(addu, 39, 0xFC00003F, 0x07FFFFC1, 0x04000000);
+    DO_MIPS32_r(addu, 40, 0xFE00007F, 0x03FFFF81, 0x02000000);
+    DO_MIPS32_r(addu, 41, 0xFF0000FF, 0x01FFFF01, 0x01000000);
+    DO_MIPS32_r(addu, 42, 0xFF8001FF, 0x00FFFE01, 0x00800000);
+    DO_MIPS32_r(addu, 43, 0xFFC003FF, 0x007FFC01, 0x00400000);
+    DO_MIPS32_r(addu, 44, 0xFFE007FF, 0x003FF801, 0x00200000);
+    DO_MIPS32_r(addu, 45, 0xFFF00FFF, 0x001FF001, 0x00100000);
+    DO_MIPS32_r(addu, 46, 0xFFF81FFF, 0x000FE001, 0x00080000);
+    DO_MIPS32_r(addu, 47, 0xFFFC3FFF, 0x0007C001, 0x00040000);
+    DO_MIPS32_r(addu, 48, 0xFFFE7FFF, 0x00038001, 0x00020000);
+    DO_MIPS32_r(addu, 49, 0xFFFFFFFF, 0x00010001, 0x00010000);
+    DO_MIPS32_r(addu, 50, 0xFFFFFFFF, 0x00018001, 0x00018000);
+    DO_MIPS32_r(addu, 51, 0xFFFE7FFF, 0x00024001, 0x0000C000);
+    DO_MIPS32_r(addu, 52, 0xFFFC3FFF, 0x00042001, 0x00006000);
+    DO_MIPS32_r(addu, 53, 0xFFF81FFF, 0x00081001, 0x00003000);
+    DO_MIPS32_r(addu, 54, 0xFFF00FFF, 0x00100801, 0x00001800);
+    DO_MIPS32_r(addu, 55, 0xFFE007FF, 0x00200401, 0x00000C00);
+    DO_MIPS32_r(addu, 56, 0xFFC003FF, 0x00400201, 0x00000600);
+    DO_MIPS32_r(addu, 57, 0xFF8001FF, 0x00800101, 0x00000300);
+    DO_MIPS32_r(addu, 58, 0xFF0000FF, 0x01000081, 0x00000180);
+    DO_MIPS32_r(addu, 59, 0xFE00007F, 0x02000041, 0x000000C0);
+    DO_MIPS32_r(addu, 60, 0xFC00003F, 0x04000021, 0x00000060);
+    DO_MIPS32_r(addu, 61, 0xF800001F, 0x08000011, 0x00000030);
+    DO_MIPS32_r(addu, 62, 0xF000000F, 0x10000009, 0x00000018);
+    DO_MIPS32_r(addu, 63, 0xE0000007, 0x20000005, 0x0000000C);
+    DO_MIPS32_r(addu, 64, 0xC0000003, 0x40000003, 0x00000006);
+    DO_MIPS32_r(addu, 65, 0x80000001, 0x80000001, 0x00000002);
+    DO_MIPS32_r(addu, 66, 0x00000000, 0x55555555, 0x55555555);
+    DO_MIPS32_r(addu, 67, 0x15555555, 0x55555555, 0x6AAAAAAA);
+    DO_MIPS32_r(addu, 68, 0xAAAAAAAA, 0x55555555, 0xFFFFFFFF);
+    DO_MIPS32_r(addu, 69, 0xFFFFFFFF, 0x55555555, 0x55555554);
+    DO_MIPS32_r(addu, 70, 0xAAAAAAAA, 0x00000000, 0xAAAAAAAA);
+    DO_MIPS32_r(addu, 71, 0xAAAAAAAA, 0x55555555, 0xFFFFFFFF);
+    DO_MIPS32_r(addu, 72, 0xAAAAAAAA, 0x2AAAAAAA, 0xD5555554);
+    DO_MIPS32_r(addu, 73, 0xAAAAAAAA, 0xFFFFFFFF, 0xAAAAAAA9);
+    DO_MIPS32_r(addu, 74, 0x7FFFFFFF, 0x00000001, 0x80000000);
+    DO_MIPS32_r(addu, 75, 0x7FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFE);
+    DO_MIPS32_r(addu, 76, 0x80000000, 0xFFFFFFFF, 0x7FFFFFFF);
+    DO_MIPS32_r(addu, 77, 0x80000000, 0x80000000, 0x00000000);
+    DO_MIPS32_r(addu, 78, 0x7FFFFFFF, 0x00000001, 0x80000000);
+    DO_MIPS32_r(addu, 79, 0x7FFFFFFF, 0x00007FFF, 0x80007FFE);
+    DO_MIPS32_r(addu, 80, 0x80000000, 0x0000FFFF, 0x8000FFFF);
+    DO_MIPS32_r(addu, 81, 0x80000000, 0x00008000, 0x80008000);
+    DO_MIPS32_r(addu, 82, 0x7FFFAAAA, 0x0000555F, 0x80000009);
+    DO_MIPS32_r(addu, 83, 0x7FFF5555, 0x0000AAAA, 0x7FFFFFFF);
+    DO_MIPS32_r(addu, 84, 0x7FFFFFFF, 0x00000002, 0x80000001);
+    DO_MIPS32_r(addu, 85, 0x7FFFFFFF, 0x00000004, 0x80000003);
+    DO_MIPS32_r(addu, 86, 0x7FFFFFFF, 0x00000008, 0x80000007);
+    DO_MIPS32_r(addu, 87, 0x7FFFFFFF, 0x00000010, 0x8000000F);
+    DO_MIPS32_r(addu, 88, 0x7FFFFFFF, 0x00000020, 0x8000001F);
+    DO_MIPS32_r(addu, 89, 0x7FFFFFFF, 0x00000040, 0x8000003F);
+    DO_MIPS32_r(addu, 90, 0x7FFFFFFF, 0x00000080, 0x8000007F);
+    DO_MIPS32_r(addu, 91, 0x7FFFFFFF, 0x00000100, 0x800000FF);
+    DO_MIPS32_r(addu, 92, 0x7FFFFFFF, 0x00000200, 0x800001FF);
+    DO_MIPS32_r(addu, 93, 0x7FFFFFFF, 0x00000400, 0x800003FF);
+    DO_MIPS32_r(addu, 94, 0x7FFFFFFF, 0x00000800, 0x800007FF);
+    DO_MIPS32_r(addu, 95, 0x7FFFFFFF, 0x00001000, 0x80000FFF);
+    DO_MIPS32_r(addu, 96, 0x7FFFFFFF, 0x00002000, 0x80001FFF);
+    DO_MIPS32_r(addu, 97, 0x7FFFFFFF, 0x00004000, 0x80003FFF);
+    DO_MIPS32_r(addu, 98, 0x7FFFFFFF, 0x00001000, 0x80003FFF);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/div.c b/tests/tcg/mips/user/isa/mips32/arithmatic/div.c
new file mode 100644
index 0000000000..5eafca326e
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/div.c
@@ -0,0 +1,81 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r2_s(div, 0, 0, 0, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(div, 1, 0, 0, 0x80000001, 0x00000001, 0x00000000, 0x80000001);
+    DO_MIPS32_r2_s(div, 2, 0, 0, 0x40000002, 0x00000003, 0x00000000, 0x15555556);
+    DO_MIPS32_r2_s(div, 3, 0, 0, 0x20000004, 0x00000007, 0x00000001, 0x04924925);
+    DO_MIPS32_r2_s(div, 4, 0, 0, 0x10000008, 0x0000000F, 0x00000009, 0x01111111);
+    DO_MIPS32_r2_s(div, 5, 0, 0, 0x88000010, 0x0000001F, 0xFFFFFFF3, 0xFC210843);
+    DO_MIPS32_r2_s(div, 6, 0, 0, 0x44000020, 0x0000003F, 0x00000025, 0x01145145);
+    DO_MIPS32_r2_s(div, 7, 0, 0, 0x22000040, 0x0000007F, 0x00000052, 0x00448912);
+    DO_MIPS32_r2_s(div, 8, 0, 0, 0x11000080, 0x000000FF, 0x00000091, 0x00111111);
+    DO_MIPS32_r2_s(div, 9, 0, 0, 0x80800100, 0x000001FF, 0xFFFFFF11, 0xFFC02011);
+    DO_MIPS32_r2_s(div, 10, 0, 0, 0x40400200, 0x000003FF, 0x00000205, 0x00101405);
+    DO_MIPS32_r2_s(div, 11, 0, 0, 0x20200400, 0x000007FF, 0x00000081, 0x00040481);
+    DO_MIPS32_r2_s(div, 12, 0, 0, 0x10100800, 0x00000FFF, 0x00000910, 0x00010110);
+    DO_MIPS32_r2_s(div, 13, 0, 0, 0x80081000, 0x00001FFF, 0xFFFFF021, 0xFFFC0021);
+    DO_MIPS32_r2_s(div, 14, 0, 0, 0x40042000, 0x00003FFF, 0x00002014, 0x00010014);
+    DO_MIPS32_r2_s(div, 15, 0, 0, 0x20024000, 0x00007FFF, 0x00000005, 0x00004005);
+    DO_MIPS32_r2_s(div, 16, 0, 0, 0x10018000, 0x0000FFFF, 0x00009001, 0x00001001);
+    DO_MIPS32_r2_s(div, 17, 0, 0, 0x80018000, 0x0001FFFF, 0xFFFF4001, 0xFFFFC001);
+    DO_MIPS32_r2_s(div, 18, 0, 0, 0x40024000, 0x0003FFFF, 0x00025000, 0x00001000);
+    DO_MIPS32_r2_s(div, 19, 0, 0, 0x20042000, 0x0007FFFF, 0x00042400, 0x00000400);
+    DO_MIPS32_r2_s(div, 20, 0, 0, 0x10081000, 0x000FFFFF, 0x00081100, 0x00000100);
+    DO_MIPS32_r2_s(div, 21, 0, 0, 0x80100800, 0x001FFFFF, 0xFFF00401, 0xFFFFFC01);
+    DO_MIPS32_r2_s(div, 22, 0, 0, 0x40200400, 0x003FFFFF, 0x00200500, 0x00000100);
+    DO_MIPS32_r2_s(div, 23, 0, 0, 0x20400200, 0x007FFFFF, 0x00400240, 0x00000040);
+    DO_MIPS32_r2_s(div, 24, 0, 0, 0x10800100, 0x00FFFFFF, 0x00800110, 0x00000010);
+    DO_MIPS32_r2_s(div, 25, 0, 0, 0x81000080, 0x01FFFFFF, 0xFF000041, 0xFFFFFFC1);
+    DO_MIPS32_r2_s(div, 26, 0, 0, 0x42000040, 0x03FFFFFF, 0x02000050, 0x00000010);
+    DO_MIPS32_r2_s(div, 27, 0, 0, 0x24000020, 0x07FFFFFF, 0x04000024, 0x00000004);
+    DO_MIPS32_r2_s(div, 28, 0, 0, 0x18000010, 0x0FFFFFFF, 0x08000011, 0x00000001);
+    DO_MIPS32_r2_s(div, 29, 0, 0, 0x90000008, 0x1FFFFFFF, 0xF0000005, 0xFFFFFFFD);
+    DO_MIPS32_r2_s(div, 30, 0, 0, 0x60000004, 0x3FFFFFFF, 0x20000005, 0x00000001);
+    DO_MIPS32_r2_s(div, 31, 0, 0, 0x60000002, 0x7FFFFFFF, 0x60000002, 0x00000000);
+    DO_MIPS32_r2_s(div, 32, 0, 0, 0x90000001, 0xFFFFFFFF, 0x00000000, 0x6FFFFFFF);
+    DO_MIPS32_r2_s(div, 33, 0, 0, 0x00000000, 0x55555555, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(div, 34, 0, 0, 0x55555555, 0x55555555, 0x00000000, 0x00000001);
+    DO_MIPS32_r2_s(div, 35, 0, 0, 0xAAAAAAAA, 0x55555555, 0xFFFFFFFF, 0xFFFFFFFF);
+    DO_MIPS32_r2_s(div, 36, 0, 0, 0xFFFFFFFF, 0x55555555, 0xFFFFFFFF, 0x00000000);
+    DO_MIPS32_r2_s(div, 37, 0, 0, 0xAAAAAAAA, 0x00000001, 0x00000000, 0xAAAAAAAA);
+    DO_MIPS32_r2_s(div, 38, 0, 0, 0xAAAAAAAA, 0x55555555, 0xFFFFFFFF, 0xFFFFFFFF);
+    DO_MIPS32_r2_s(div, 39, 0, 0, 0xAAAAAAAA, 0xAAAAAAAA, 0x00000000, 0x00000001);
+    DO_MIPS32_r2_s(div, 40, 0, 0, 0xAAAAAAAA, 0xFFFFFFFF, 0x00000000, 0x55555556);
+    DO_MIPS32_r2_s(div, 41, 0, 0, 0x7FFFFFFF, 0x7FFFFFFF, 0x00000000, 0x00000001);
+    DO_MIPS32_r2_s(div, 42, 0, 0, 0x7FFFFFFF, 0x80000000, 0x7FFFFFFF, 0x00000000);
+    DO_MIPS32_r2_s(div, 43, 0, 0, 0x7FFFFFFF, 0xFFFFFFFF, 0x00000000, 0x80000001);
+    DO_MIPS32_r2_s(div, 44, 0, 0, 0x80000000, 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+    DO_MIPS32_r2_s(div, 45, 0, 0, 0x80000000, 0x80000000, 0x00000000, 0x00000001);
+#if 0
+    /* Disabled until we find a way to disable assembler trap */
+    DO_MIPS32_r2_s(div, 46, 0, 0, 0x80000000, 0xFFFFFFFF, 0x00000000, 0x80000000);
+#endif
+    DO_MIPS32_r2_s(div, 47, 0, 0, 0xFFFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF, 0x00000000);
+    DO_MIPS32_r2_s(div, 48, 0, 0, 0xFFFFFFFF, 0x80000000, 0xFFFFFFFF, 0x00000000);
+    DO_MIPS32_r2_s(div, 49, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000001);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/divu.c b/tests/tcg/mips/user/isa/mips32/arithmatic/divu.c
new file mode 100644
index 0000000000..172e8af693
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/divu.c
@@ -0,0 +1,78 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r2_s(divu, 0, 0, 0, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(divu, 1, 0, 0, 0x80000001, 0x00000001, 0x00000000, 0x80000001);
+    DO_MIPS32_r2_s(divu, 2, 0, 0, 0x40000002, 0x00000003, 0x00000000, 0x15555556);
+    DO_MIPS32_r2_s(divu, 3, 0, 0, 0x20000004, 0x00000007, 0x00000001, 0x04924925);
+    DO_MIPS32_r2_s(divu, 4, 0, 0, 0x10000008, 0x0000000F, 0x00000009, 0x01111111);
+    DO_MIPS32_r2_s(divu, 5, 0, 0, 0x88000010, 0x0000001F, 0x00000016, 0x046318C6);
+    DO_MIPS32_r2_s(divu, 6, 0, 0, 0x44000020, 0x0000003F, 0x00000025, 0x01145145);
+    DO_MIPS32_r2_s(divu, 7, 0, 0, 0x22000040, 0x0000007F, 0x00000052, 0x00448912);
+    DO_MIPS32_r2_s(divu, 8, 0, 0, 0x11000080, 0x000000FF, 0x00000091, 0x00111111);
+    DO_MIPS32_r2_s(divu, 9, 0, 0, 0x80800100, 0x000001FF, 0x00000130, 0x00406030);
+    DO_MIPS32_r2_s(divu, 10, 0, 0, 0x40400200, 0x000003FF, 0x00000205, 0x00101405);
+    DO_MIPS32_r2_s(divu, 11, 0, 0, 0x20200400, 0x000007FF, 0x00000081, 0x00040481);
+    DO_MIPS32_r2_s(divu, 12, 0, 0, 0x10100800, 0x00000FFF, 0x00000910, 0x00010110);
+    DO_MIPS32_r2_s(divu, 13, 0, 0, 0x80081000, 0x00001FFF, 0x00001060, 0x00040060);
+    DO_MIPS32_r2_s(divu, 14, 0, 0, 0x40042000, 0x00003FFF, 0x00002014, 0x00010014);
+    DO_MIPS32_r2_s(divu, 15, 0, 0, 0x20024000, 0x00007FFF, 0x00000005, 0x00004005);
+    DO_MIPS32_r2_s(divu, 16, 0, 0, 0x10018000, 0x0000FFFF, 0x00009001, 0x00001001);
+    DO_MIPS32_r2_s(divu, 17, 0, 0, 0x80018000, 0x0001FFFF, 0x0001C000, 0x00004000);
+    DO_MIPS32_r2_s(divu, 18, 0, 0, 0x40024000, 0x0003FFFF, 0x00025000, 0x00001000);
+    DO_MIPS32_r2_s(divu, 19, 0, 0, 0x20042000, 0x0007FFFF, 0x00042400, 0x00000400);
+    DO_MIPS32_r2_s(divu, 20, 0, 0, 0x10081000, 0x000FFFFF, 0x00081100, 0x00000100);
+    DO_MIPS32_r2_s(divu, 21, 0, 0, 0x80100800, 0x001FFFFF, 0x00100C00, 0x00000400);
+    DO_MIPS32_r2_s(divu, 22, 0, 0, 0x40200400, 0x003FFFFF, 0x00200500, 0x00000100);
+    DO_MIPS32_r2_s(divu, 23, 0, 0, 0x20400200, 0x007FFFFF, 0x00400240, 0x00000040);
+    DO_MIPS32_r2_s(divu, 24, 0, 0, 0x10800100, 0x00FFFFFF, 0x00800110, 0x00000010);
+    DO_MIPS32_r2_s(divu, 25, 0, 0, 0x81000080, 0x01FFFFFF, 0x010000C0, 0x00000040);
+    DO_MIPS32_r2_s(divu, 26, 0, 0, 0x42000040, 0x03FFFFFF, 0x02000050, 0x00000010);
+    DO_MIPS32_r2_s(divu, 27, 0, 0, 0x24000020, 0x07FFFFFF, 0x04000024, 0x00000004);
+    DO_MIPS32_r2_s(divu, 28, 0, 0, 0x18000010, 0x0FFFFFFF, 0x08000011, 0x00000001);
+    DO_MIPS32_r2_s(divu, 29, 0, 0, 0x90000008, 0x1FFFFFFF, 0x1000000C, 0x00000004);
+    DO_MIPS32_r2_s(divu, 30, 0, 0, 0x60000004, 0x3FFFFFFF, 0x20000005, 0x00000001);
+    DO_MIPS32_r2_s(divu, 31, 0, 0, 0x60000002, 0x7FFFFFFF, 0x60000002, 0x00000000);
+    DO_MIPS32_r2_s(divu, 32, 0, 0, 0x90000001, 0xFFFFFFFF, 0x90000001, 0x00000000);
+    DO_MIPS32_r2_s(divu, 33, 0, 0, 0x00000000, 0x55555555, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(divu, 34, 0, 0, 0x55555555, 0x55555555, 0x00000000, 0x00000001);
+    DO_MIPS32_r2_s(divu, 35, 0, 0, 0xAAAAAAAA, 0x55555555, 0x00000000, 0x00000002);
+    DO_MIPS32_r2_s(divu, 36, 0, 0, 0xFFFFFFFF, 0x55555555, 0x00000000, 0x00000003);
+    DO_MIPS32_r2_s(divu, 37, 0, 0, 0xAAAAAAAA, 0x00000001, 0x00000000, 0xAAAAAAAA);
+    DO_MIPS32_r2_s(divu, 38, 0, 0, 0xAAAAAAAA, 0x55555555, 0x00000000, 0x00000002);
+    DO_MIPS32_r2_s(divu, 39, 0, 0, 0xAAAAAAAA, 0xAAAAAAAA, 0x00000000, 0x00000001);
+    DO_MIPS32_r2_s(divu, 40, 0, 0, 0xAAAAAAAA, 0xFFFFFFFF, 0xAAAAAAAA, 0x00000000);
+    DO_MIPS32_r2_s(divu, 41, 0, 0, 0x7FFFFFFF, 0x7FFFFFFF, 0x00000000, 0x00000001);
+    DO_MIPS32_r2_s(divu, 42, 0, 0, 0x7FFFFFFF, 0x80000000, 0x7FFFFFFF, 0x00000000);
+    DO_MIPS32_r2_s(divu, 43, 0, 0, 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF, 0x00000000);
+    DO_MIPS32_r2_s(divu, 44, 0, 0, 0x80000000, 0x7FFFFFFF, 0x00000001, 0x00000001);
+    DO_MIPS32_r2_s(divu, 45, 0, 0, 0x80000000, 0x80000000, 0x00000000, 0x00000001);
+    DO_MIPS32_r2_s(divu, 46, 0, 0, 0x80000000, 0xFFFFFFFF, 0x80000000, 0x00000000);
+    DO_MIPS32_r2_s(divu, 47, 0, 0, 0xFFFFFFFF, 0x7FFFFFFF, 0x00000001, 0x00000002);
+    DO_MIPS32_r2_s(divu, 48, 0, 0, 0xFFFFFFFF, 0x80000000, 0x7FFFFFFF, 0x00000001);
+    DO_MIPS32_r2_s(divu, 49, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000001);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/madd.c b/tests/tcg/mips/user/isa/mips32/arithmatic/madd.c
new file mode 100644
index 0000000000..7f047f76d9
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/madd.c
@@ -0,0 +1,79 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r2_s(divu, 0, 0, 0, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(madd, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(madd, 1, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000001);
+    DO_MIPS32_r2_s(madd, 2, 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000000, 0x00000007);
+    DO_MIPS32_r2_s(madd, 3, 0x00000000, 0x00000007, 0x00000004, 0x00000007, 0x00000000, 0x00000023);
+    DO_MIPS32_r2_s(madd, 4, 0x00000000, 0x00000023, 0x00000008, 0x0000000F, 0x00000000, 0x0000009b);
+    DO_MIPS32_r2_s(madd, 5, 0x00000000, 0x0000009b, 0x00000010, 0x0000001F, 0x00000000, 0x0000028b);
+    DO_MIPS32_r2_s(madd, 6, 0x00000000, 0x0000028b, 0x00000020, 0x0000003F, 0x00000000, 0x00000a6b);
+    DO_MIPS32_r2_s(madd, 7, 0x00000000, 0x00000a6b, 0x00000040, 0x0000007F, 0x00000000, 0x00002a2b);
+    DO_MIPS32_r2_s(madd, 8, 0x00000000, 0x00002a2b, 0x00000080, 0x000000FF, 0x00000000, 0x0000a9ab);
+    DO_MIPS32_r2_s(madd, 9, 0x00000000, 0x0000a9ab, 0x00000100, 0x000001FF, 0x00000000, 0x0002a8ab);
+    DO_MIPS32_r2_s(madd, 10, 0x00000000, 0x0002a8ab, 0x00000200, 0x000003FF, 0x00000000, 0x000aa6ab);
+    DO_MIPS32_r2_s(madd, 11, 0x00000000, 0x000aa6ab, 0x00000400, 0x000007FF, 0x00000000, 0x002aa2ab);
+    DO_MIPS32_r2_s(madd, 12, 0x00000000, 0x002aa2ab, 0x00000800, 0x00000FFF, 0x00000000, 0x00aa9aab);
+    DO_MIPS32_r2_s(madd, 13, 0x00000000, 0x00aa9aab, 0x00001000, 0x00001FFF, 0x00000000, 0x02aa8aab);
+    DO_MIPS32_r2_s(madd, 14, 0x00000000, 0x02aa8aab, 0x00002000, 0x00003FFF, 0x00000000, 0x0aaa6aab);
+    DO_MIPS32_r2_s(madd, 15, 0x00000000, 0x0aaa6aab, 0x00004000, 0x00007FFF, 0x00000000, 0x2aaa2aab);
+    DO_MIPS32_r2_s(madd, 16, 0x00000000, 0x2aaa2aab, 0x00008000, 0x0000FFFF, 0x00000000, 0xaaa9aaab);
+    DO_MIPS32_r2_s(madd, 17, 0x00000000, 0xaaa9aaab, 0x00010000, 0x0001FFFF, 0x00000002, 0xaaa8aaab);
+    DO_MIPS32_r2_s(madd, 18, 0x00000002, 0xaaa8aaab, 0x00020000, 0x0003FFFF, 0x0000000a, 0xAAA6AAAB);
+    DO_MIPS32_r2_s(madd, 19, 0x0000000a, 0xAAA6AAAB, 0x00040000, 0x0007FFFF, 0x0000002A, 0xAAA2AAAB);
+    DO_MIPS32_r2_s(madd, 20, 0x0000002A, 0xAAA2AAAB, 0x00080000, 0x000FFFFF, 0x000000AA, 0xAA9AAAAB);
+    DO_MIPS32_r2_s(madd, 21, 0x000000AA, 0xAA9AAAAB, 0x00100000, 0x001FFFFF, 0x000002AA, 0xAA8AAAAB);
+    DO_MIPS32_r2_s(madd, 22, 0x000002AA, 0xAA8AAAAB, 0x00200000, 0x003FFFFF, 0x00000AAA, 0xAA6AAAAB);
+    DO_MIPS32_r2_s(madd, 23, 0x00000AAA, 0xAA6AAAAB, 0x00400000, 0x007FFFFF, 0x00002AAA, 0xAA2AAAAB);
+    DO_MIPS32_r2_s(madd, 24, 0x00002AAA, 0xAA2AAAAB, 0x00800000, 0x00FFFFFF, 0x0000AAAA, 0xA9AAAAAB);
+    DO_MIPS32_r2_s(madd, 25, 0x0000AAAA, 0xA9AAAAAB, 0x01000000, 0x01FFFFFF, 0x0002AAAA, 0xA8AAAAAB);
+    DO_MIPS32_r2_s(madd, 26, 0x0002AAAA, 0xA8AAAAAB, 0x02000000, 0x03FFFFFF, 0x000AAAAA, 0xA6AAAAAB);
+    DO_MIPS32_r2_s(madd, 27, 0x000AAAAA, 0xA6AAAAAB, 0x04000000, 0x07FFFFFF, 0x002AAAAA, 0xA2AAAAAB);
+    DO_MIPS32_r2_s(madd, 28, 0x002AAAAA, 0xA2AAAAAB, 0x08000000, 0x0FFFFFFF, 0x00AAAAAA, 0x9AAAAAAB);
+    DO_MIPS32_r2_s(madd, 29, 0x00AAAAAA, 0x9AAAAAAB, 0x10000000, 0x1FFFFFFF, 0x02AAAAAA, 0x8AAAAAAB);
+    DO_MIPS32_r2_s(madd, 30, 0x02AAAAAA, 0x8AAAAAAB, 0x20000000, 0x3FFFFFFF, 0x0AAAAAAA, 0x6AAAAAAB);
+    DO_MIPS32_r2_s(madd, 31, 0x0AAAAAAA, 0x6AAAAAAB, 0x40000000, 0x7FFFFFFF, 0x2AAAAAAA, 0x2AAAAAAB);
+    DO_MIPS32_r2_s(madd, 32, 0x2AAAAAAA, 0x2AAAAAAB, 0x80000000, 0xFFFFFFFF, 0x2AAAAAAA, 0xAAAAAAAB);
+    DO_MIPS32_r2_s(madd, 33, 0x00000000, 0x00000000, 0x00000000, 0x55555555, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(madd, 34, 0x00000000, 0x00000000, 0x55555555, 0x55555555, 0x1C71C71C, 0x38E38E39);
+    DO_MIPS32_r2_s(madd, 35, 0x1C71C71C, 0x38E38E39, 0xAAAAAAAA, 0x55555555, 0xFFFFFFFF, 0xAAAAAAAB);
+    DO_MIPS32_r2_s(madd, 36, 0xFFFFFFFF, 0xAAAAAAAB, 0xFFFFFFFF, 0x55555555, 0xFFFFFFFF, 0x55555556);
+    DO_MIPS32_r2_s(madd, 37, 0xFFFFFFFF, 0x55555556, 0xAAAAAAAA, 0x00000000, 0xFFFFFFFF, 0x55555556);
+    DO_MIPS32_r2_s(madd, 38, 0xFFFFFFFF, 0x55555556, 0xAAAAAAAA, 0x55555555, 0xe38e38e2, 0xc71c71c8);
+    DO_MIPS32_r2_s(madd, 39, 0xe38e38e2, 0xc71c71c8, 0xAAAAAAAA, 0xAAAAAAAA, 0xffffffff, 0xaaaaaaac);
+    DO_MIPS32_r2_s(madd, 40, 0xffffffff, 0xaaaaaaac, 0xAAAAAAAA, 0xFFFFFFFF, 0x00000000, 0x00000002);
+    DO_MIPS32_r2_s(madd, 41, 0x00000000, 0x00000000, 0x7FFFFFFF, 0x7FFFFFFF, 0x3FFFFFFF, 0x00000001);
+    DO_MIPS32_r2_s(madd, 42, 0x3FFFFFFF, 0x00000001, 0x7FFFFFFF, 0x80000000, 0xffffffff, 0x80000001);
+    DO_MIPS32_r2_s(madd, 43, 0xffffffff, 0x80000001, 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002);
+    DO_MIPS32_r2_s(madd, 44, 0xFFFFFFFF, 0x00000002, 0x80000000, 0x7FFFFFFF, 0xbfffffff, 0x80000002);
+    DO_MIPS32_r2_s(madd, 45, 0xbfffffff, 0x80000002, 0x80000000, 0x80000000, 0xffffffff, 0x80000002);
+    DO_MIPS32_r2_s(madd, 46, 0xffffffff, 0x80000002, 0x80000000, 0xFFFFFFFF, 0x00000000, 0x00000002);
+    DO_MIPS32_r2_s(madd, 47, 0x00000000, 0x00000002, 0xFFFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF, 0x80000003);
+    DO_MIPS32_r2_s(madd, 48, 0xFFFFFFFF, 0x80000003, 0xFFFFFFFF, 0x80000000, 0x00000000, 0x00000003);
+    DO_MIPS32_r2_s(madd, 49, 0x00000000, 0x00000003, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000004);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/maddu.c b/tests/tcg/mips/user/isa/mips32/arithmatic/maddu.c
new file mode 100644
index 0000000000..8073841b33
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/maddu.c
@@ -0,0 +1,78 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r2_s(maddu, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(maddu, 1, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000001);
+    DO_MIPS32_r2_s(maddu, 2, 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000000, 0x00000007);
+    DO_MIPS32_r2_s(maddu, 3, 0x00000000, 0x00000007, 0x00000004, 0x00000007, 0x00000000, 0x00000023);
+    DO_MIPS32_r2_s(maddu, 4, 0x00000000, 0x00000023, 0x00000008, 0x0000000F, 0x00000000, 0x0000009b);
+    DO_MIPS32_r2_s(maddu, 5, 0x00000000, 0x0000009b, 0x00000010, 0x0000001F, 0x00000000, 0x0000028b);
+    DO_MIPS32_r2_s(maddu, 6, 0x00000000, 0x0000028b, 0x00000020, 0x0000003F, 0x00000000, 0x00000a6b);
+    DO_MIPS32_r2_s(maddu, 7, 0x00000000, 0x00000a6b, 0x00000040, 0x0000007F, 0x00000000, 0x00002a2b);
+    DO_MIPS32_r2_s(maddu, 8, 0x00000000, 0x00002a2b, 0x00000080, 0x000000FF, 0x00000000, 0x0000a9ab);
+    DO_MIPS32_r2_s(maddu, 9, 0x00000000, 0x0000a9ab, 0x00000100, 0x000001FF, 0x00000000, 0x0002a8ab);
+    DO_MIPS32_r2_s(maddu, 10, 0x00000000, 0x0002a8ab, 0x00000200, 0x000003FF, 0x00000000, 0x000aa6ab);
+    DO_MIPS32_r2_s(maddu, 11, 0x00000000, 0x000aa6ab, 0x00000400, 0x000007FF, 0x00000000, 0x002aa2ab);
+    DO_MIPS32_r2_s(maddu, 12, 0x00000000, 0x002aa2ab, 0x00000800, 0x00000FFF, 0x00000000, 0x00aa9aab);
+    DO_MIPS32_r2_s(maddu, 13, 0x00000000, 0x00aa9aab, 0x00001000, 0x00001FFF, 0x00000000, 0x02aa8aab);
+    DO_MIPS32_r2_s(maddu, 14, 0x00000000, 0x02aa8aab, 0x00002000, 0x00003FFF, 0x00000000, 0x0aaa6aab);
+    DO_MIPS32_r2_s(maddu, 15, 0x00000000, 0x0aaa6aab, 0x00004000, 0x00007FFF, 0x00000000, 0x2aaa2aab);
+    DO_MIPS32_r2_s(maddu, 16, 0x00000000, 0x2aaa2aab, 0x00008000, 0x0000FFFF, 0x00000000, 0xaaa9aaab);
+    DO_MIPS32_r2_s(maddu, 17, 0x00000000, 0xaaa9aaab, 0x00010000, 0x0001FFFF, 0x00000002, 0xaaa8aaab);
+    DO_MIPS32_r2_s(maddu, 18, 0x00000002, 0xaaa8aaab, 0x00020000, 0x0003FFFF, 0x0000000a, 0xAAA6AAAB);
+    DO_MIPS32_r2_s(maddu, 19, 0x0000000a, 0xAAA6AAAB, 0x00040000, 0x0007FFFF, 0x0000002A, 0xAAA2AAAB);
+    DO_MIPS32_r2_s(maddu, 20, 0x0000002A, 0xAAA2AAAB, 0x00080000, 0x000FFFFF, 0x000000AA, 0xAA9AAAAB);
+    DO_MIPS32_r2_s(maddu, 21, 0x000000AA, 0xAA9AAAAB, 0x00100000, 0x001FFFFF, 0x000002AA, 0xAA8AAAAB);
+    DO_MIPS32_r2_s(maddu, 22, 0x000002AA, 0xAA8AAAAB, 0x00200000, 0x003FFFFF, 0x00000AAA, 0xAA6AAAAB);
+    DO_MIPS32_r2_s(maddu, 23, 0x00000AAA, 0xAA6AAAAB, 0x00400000, 0x007FFFFF, 0x00002AAA, 0xAA2AAAAB);
+    DO_MIPS32_r2_s(maddu, 24, 0x00002AAA, 0xAA2AAAAB, 0x00800000, 0x00FFFFFF, 0x0000AAAA, 0xA9AAAAAB);
+    DO_MIPS32_r2_s(maddu, 25, 0x0000AAAA, 0xA9AAAAAB, 0x01000000, 0x01FFFFFF, 0x0002AAAA, 0xA8AAAAAB);
+    DO_MIPS32_r2_s(maddu, 26, 0x0002AAAA, 0xA8AAAAAB, 0x02000000, 0x03FFFFFF, 0x000AAAAA, 0xA6AAAAAB);
+    DO_MIPS32_r2_s(maddu, 27, 0x000AAAAA, 0xA6AAAAAB, 0x04000000, 0x07FFFFFF, 0x002AAAAA, 0xA2AAAAAB);
+    DO_MIPS32_r2_s(maddu, 28, 0x002AAAAA, 0xA2AAAAAB, 0x08000000, 0x0FFFFFFF, 0x00AAAAAA, 0x9AAAAAAB);
+    DO_MIPS32_r2_s(maddu, 29, 0x00AAAAAA, 0x9AAAAAAB, 0x10000000, 0x1FFFFFFF, 0x02AAAAAA, 0x8AAAAAAB);
+    DO_MIPS32_r2_s(maddu, 30, 0x02AAAAAA, 0x8AAAAAAB, 0x20000000, 0x3FFFFFFF, 0x0AAAAAAA, 0x6AAAAAAB);
+    DO_MIPS32_r2_s(maddu, 31, 0x0AAAAAAA, 0x6AAAAAAB, 0x40000000, 0x7FFFFFFF, 0x2AAAAAAA, 0x2AAAAAAB);
+    DO_MIPS32_r2_s(maddu, 32, 0x2AAAAAAA, 0x2AAAAAAB, 0x80000000, 0xFFFFFFFF, 0xAAAAAAA9, 0xAAAAAAAB);
+    DO_MIPS32_r2_s(maddu, 33, 0x00000000, 0x00000000, 0x00000000, 0x55555555, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(maddu, 34, 0x00000000, 0x00000000, 0x55555555, 0x55555555, 0x1C71C71C, 0x38E38E39);
+    DO_MIPS32_r2_s(maddu, 35, 0x1C71C71C, 0x38E38E39, 0xAAAAAAAA, 0x55555555, 0x55555554, 0xaaaaaaab);
+    DO_MIPS32_r2_s(maddu, 36, 0x55555554, 0xaaaaaaab, 0xFFFFFFFF, 0x55555555, 0xaaaaaaa9, 0x55555556);
+    DO_MIPS32_r2_s(maddu, 37, 0xaaaaaaa9, 0x55555556, 0xAAAAAAAA, 0x00000000, 0xaaaaaaa9, 0x55555556);
+    DO_MIPS32_r2_s(maddu, 38, 0xaaaaaaa9, 0x55555556, 0xAAAAAAAA, 0x55555555, 0xe38e38e1, 0xc71c71c8);
+    DO_MIPS32_r2_s(maddu, 39, 0xe38e38e1, 0xc71c71c8, 0xAAAAAAAA, 0xAAAAAAAA, 0x55555552, 0xaaaaaaac);
+    DO_MIPS32_r2_s(maddu, 40, 0x55555552, 0xaaaaaaac, 0xAAAAAAAA, 0xFFFFFFFF, 0xfffffffc, 0x00000002);
+    DO_MIPS32_r2_s(maddu, 41, 0x00000000, 0x00000000, 0x7FFFFFFF, 0x7FFFFFFF, 0x3fffffff, 0x00000001);
+    DO_MIPS32_r2_s(maddu, 42, 0x3fffffff, 0x00000001, 0x7FFFFFFF, 0x80000000, 0x7ffffffe, 0x80000001);
+    DO_MIPS32_r2_s(maddu, 43, 0x7ffffffe, 0x80000001, 0x7FFFFFFF, 0xFFFFFFFF, 0xfffffffd, 0x00000002);
+    DO_MIPS32_r2_s(maddu, 44, 0xfffffffd, 0x00000002, 0x80000000, 0x7FFFFFFF, 0x3ffffffc, 0x80000002);
+    DO_MIPS32_r2_s(maddu, 45, 0x3ffffffc, 0x80000002, 0x80000000, 0x80000000, 0x7ffffffc, 0x80000002);
+    DO_MIPS32_r2_s(maddu, 46, 0x7ffffffc, 0x80000002, 0x80000000, 0xFFFFFFFF, 0xfffffffc, 0x00000002);
+    DO_MIPS32_r2_s(maddu, 47, 0xfffffffc, 0x00000002, 0xFFFFFFFF, 0x7FFFFFFF, 0x7ffffffa, 0x80000003);
+    DO_MIPS32_r2_s(maddu, 48, 0x7ffffffa, 0x80000003, 0xFFFFFFFF, 0x80000000, 0xfffffffa, 0x00000003);
+    DO_MIPS32_r2_s(maddu, 49, 0xfffffffa, 0x00000003, 0xFFFFFFFF, 0xFFFFFFFF, 0xfffffff8, 0x00000004);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/msub.c b/tests/tcg/mips/user/isa/mips32/arithmatic/msub.c
new file mode 100644
index 0000000000..36387cbdf8
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/msub.c
@@ -0,0 +1,78 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r2_s(msub, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(msub, 1, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0xffffffff, 0xffffffff);
+    DO_MIPS32_r2_s(msub, 2, 0xffffffff, 0xffffffff, 0x00000002, 0x00000003, 0xffffffff, 0xfffffff9);
+    DO_MIPS32_r2_s(msub, 3, 0xffffffff, 0xfffffff9, 0x00000004, 0x00000007, 0xffffffff, 0xffffffdd);
+    DO_MIPS32_r2_s(msub, 4, 0xffffffff, 0xffffffdd, 0x00000008, 0x0000000F, 0xffffffff, 0xffffff65);
+    DO_MIPS32_r2_s(msub, 5, 0xffffffff, 0xffffff65, 0x00000010, 0x0000001F, 0xffffffff, 0xfffffd75);
+    DO_MIPS32_r2_s(msub, 6, 0xffffffff, 0xfffffd75, 0x00000020, 0x0000003F, 0xffffffff, 0xfffff595);
+    DO_MIPS32_r2_s(msub, 7, 0xffffffff, 0xfffff595, 0x00000040, 0x0000007F, 0xffffffff, 0xffffd5d5);
+    DO_MIPS32_r2_s(msub, 8, 0xffffffff, 0xffffd5d5, 0x00000080, 0x000000FF, 0xffffffff, 0xffff5655);
+    DO_MIPS32_r2_s(msub, 9, 0xffffffff, 0xffff5655, 0x00000100, 0x000001FF, 0xffffffff, 0xfffd5755);
+    DO_MIPS32_r2_s(msub, 10, 0xffffffff, 0xfffd5755, 0x00000200, 0x000003FF, 0xffffffff, 0xfff55955);
+    DO_MIPS32_r2_s(msub, 11, 0xffffffff, 0xfff55955, 0x00000400, 0x000007FF, 0xffffffff, 0xffd55d55);
+    DO_MIPS32_r2_s(msub, 12, 0xffffffff, 0xffd55d55, 0x00000800, 0x00000FFF, 0xffffffff, 0xff556555);
+    DO_MIPS32_r2_s(msub, 13, 0xffffffff, 0xff556555, 0x00001000, 0x00001FFF, 0xffffffff, 0xfd557555);
+    DO_MIPS32_r2_s(msub, 14, 0xffffffff, 0xfd557555, 0x00002000, 0x00003FFF, 0xffffffff, 0xf5559555);
+    DO_MIPS32_r2_s(msub, 15, 0xffffffff, 0xf5559555, 0x00004000, 0x00007FFF, 0xffffffff, 0xd555d555);
+    DO_MIPS32_r2_s(msub, 16, 0xffffffff, 0xd555d555, 0x00008000, 0x0000FFFF, 0xffffffff, 0x55565555);
+    DO_MIPS32_r2_s(msub, 17, 0xffffffff, 0x55565555, 0x00010000, 0x0001FFFF, 0xfffffffd, 0x55575555);
+    DO_MIPS32_r2_s(msub, 18, 0xfffffffd, 0x55575555, 0x00020000, 0x0003FFFF, 0xfffffff5, 0x55595555);
+    DO_MIPS32_r2_s(msub, 19, 0xfffffff5, 0x55595555, 0x00040000, 0x0007FFFF, 0xffffffd5, 0x555d5555);
+    DO_MIPS32_r2_s(msub, 20, 0xffffffd5, 0x555d5555, 0x00080000, 0x000FFFFF, 0xffffff55, 0x55655555);
+    DO_MIPS32_r2_s(msub, 21, 0xffffff55, 0x55655555, 0x00100000, 0x001FFFFF, 0xfffffd55, 0x55755555);
+    DO_MIPS32_r2_s(msub, 22, 0xfffffd55, 0x55755555, 0x00200000, 0x003FFFFF, 0xfffff555, 0x55955555);
+    DO_MIPS32_r2_s(msub, 23, 0xfffff555, 0x55955555, 0x00400000, 0x007FFFFF, 0xffffd555, 0x55d55555);
+    DO_MIPS32_r2_s(msub, 24, 0xffffd555, 0x55d55555, 0x00800000, 0x00FFFFFF, 0xffff5555, 0x56555555);
+    DO_MIPS32_r2_s(msub, 25, 0xffff5555, 0x56555555, 0x01000000, 0x01FFFFFF, 0xfffd5555, 0x57555555);
+    DO_MIPS32_r2_s(msub, 26, 0xfffd5555, 0x57555555, 0x02000000, 0x03FFFFFF, 0xfff55555, 0x59555555);
+    DO_MIPS32_r2_s(msub, 27, 0xfff55555, 0x59555555, 0x04000000, 0x07FFFFFF, 0xffd55555, 0x5d555555);
+    DO_MIPS32_r2_s(msub, 28, 0xffd55555, 0x5d555555, 0x08000000, 0x0FFFFFFF, 0xff555555, 0x65555555);
+    DO_MIPS32_r2_s(msub, 29, 0xff555555, 0x65555555, 0x10000000, 0x1FFFFFFF, 0xfd555555, 0x75555555);
+    DO_MIPS32_r2_s(msub, 30, 0xfd555555, 0x75555555, 0x20000000, 0x3FFFFFFF, 0xf5555555, 0x95555555);
+    DO_MIPS32_r2_s(msub, 31, 0xf5555555, 0x95555555, 0x40000000, 0x7FFFFFFF, 0xd5555555, 0xd5555555);
+    DO_MIPS32_r2_s(msub, 32, 0xd5555555, 0xd5555555, 0x80000000, 0xFFFFFFFF, 0xd5555555, 0x55555555);
+    DO_MIPS32_r2_s(msub, 33, 0x00000000, 0x00000000, 0x00000000, 0x55555555, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(msub, 34, 0x00000000, 0x00000000, 0x55555555, 0x55555555, 0xe38e38e3, 0xc71c71c7);
+    DO_MIPS32_r2_s(msub, 35, 0xe38e38e3, 0xc71c71c7, 0xAAAAAAAA, 0x55555555, 0x00000000, 0x55555555);
+    DO_MIPS32_r2_s(msub, 36, 0x00000000, 0x55555555, 0xFFFFFFFF, 0x55555555, 0x00000000, 0xaaaaaaaa);
+    DO_MIPS32_r2_s(msub, 37, 0x00000000, 0xaaaaaaaa, 0xAAAAAAAA, 0x00000000, 0x00000000, 0xaaaaaaaa);
+    DO_MIPS32_r2_s(msub, 38, 0x00000000, 0xaaaaaaaa, 0xAAAAAAAA, 0x55555555, 0x1c71c71d, 0x38e38e38);
+    DO_MIPS32_r2_s(msub, 39, 0x1c71c71d, 0x38e38e38, 0xAAAAAAAA, 0xAAAAAAAA, 0x00000000, 0x55555554);
+    DO_MIPS32_r2_s(msub, 40, 0x00000000, 0x55555554, 0xAAAAAAAA, 0xFFFFFFFF, 0xffffffff, 0xfffffffe);
+    DO_MIPS32_r2_s(msub, 41, 0x00000000, 0x00000000, 0x7FFFFFFF, 0x7FFFFFFF, 0xc0000000, 0xffffffff);
+    DO_MIPS32_r2_s(msub, 42, 0xc0000000, 0xffffffff, 0x7FFFFFFF, 0x80000000, 0x00000000, 0x7fffffff);
+    DO_MIPS32_r2_s(msub, 43, 0x00000000, 0x7fffffff, 0x7FFFFFFF, 0xFFFFFFFF, 0x00000000, 0xfffffffe);
+    DO_MIPS32_r2_s(msub, 44, 0x00000000, 0xfffffffe, 0x80000000, 0x7FFFFFFF, 0x40000000, 0x7ffffffe);
+    DO_MIPS32_r2_s(msub, 45, 0x40000000, 0x7ffffffe, 0x80000000, 0x80000000, 0x00000000, 0x7ffffffe);
+    DO_MIPS32_r2_s(msub, 46, 0x00000000, 0x7ffffffe, 0x80000000, 0xFFFFFFFF, 0xffffffff, 0xfffffffe);
+    DO_MIPS32_r2_s(msub, 47, 0xffffffff, 0xfffffffe, 0xFFFFFFFF, 0x7FFFFFFF, 0x00000000, 0x7ffffffd);
+    DO_MIPS32_r2_s(msub, 48, 0x00000000, 0x7ffffffd, 0xFFFFFFFF, 0x80000000, 0xffffffff, 0xfffffffd);
+    DO_MIPS32_r2_s(msub, 49, 0xffffffff, 0xfffffffd, 0xFFFFFFFF, 0xFFFFFFFF, 0xffffffff, 0xfffffffc);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/msubu.c b/tests/tcg/mips/user/isa/mips32/arithmatic/msubu.c
new file mode 100644
index 0000000000..d20065d0b2
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/msubu.c
@@ -0,0 +1,78 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r2_s(msubu, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(msubu, 1, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0xffffffff, 0xffffffff);
+    DO_MIPS32_r2_s(msubu, 2, 0xffffffff, 0xffffffff, 0x00000002, 0x00000003, 0xffffffff, 0xfffffff9);
+    DO_MIPS32_r2_s(msubu, 3, 0xffffffff, 0xfffffff9, 0x00000004, 0x00000007, 0xffffffff, 0xffffffdd);
+    DO_MIPS32_r2_s(msubu, 4, 0xffffffff, 0xffffffdd, 0x00000008, 0x0000000F, 0xffffffff, 0xffffff65);
+    DO_MIPS32_r2_s(msubu, 5, 0xffffffff, 0xffffff65, 0x00000010, 0x0000001F, 0xffffffff, 0xfffffd75);
+    DO_MIPS32_r2_s(msubu, 6, 0xffffffff, 0xfffffd75, 0x00000020, 0x0000003F, 0xffffffff, 0xfffff595);
+    DO_MIPS32_r2_s(msubu, 7, 0xffffffff, 0xfffff595, 0x00000040, 0x0000007F, 0xffffffff, 0xffffd5d5);
+    DO_MIPS32_r2_s(msubu, 8, 0xffffffff, 0xffffd5d5, 0x00000080, 0x000000FF, 0xffffffff, 0xffff5655);
+    DO_MIPS32_r2_s(msubu, 9, 0xffffffff, 0xffff5655, 0x00000100, 0x000001FF, 0xffffffff, 0xfffd5755);
+    DO_MIPS32_r2_s(msubu, 10, 0xffffffff, 0xfffd5755, 0x00000200, 0x000003FF, 0xffffffff, 0xfff55955);
+    DO_MIPS32_r2_s(msubu, 11, 0xffffffff, 0xfff55955, 0x00000400, 0x000007FF, 0xffffffff, 0xffd55d55);
+    DO_MIPS32_r2_s(msubu, 12, 0xffffffff, 0xffd55d55, 0x00000800, 0x00000FFF, 0xffffffff, 0xff556555);
+    DO_MIPS32_r2_s(msubu, 13, 0xffffffff, 0xff556555, 0x00001000, 0x00001FFF, 0xffffffff, 0xfd557555);
+    DO_MIPS32_r2_s(msubu, 14, 0xffffffff, 0xfd557555, 0x00002000, 0x00003FFF, 0xffffffff, 0xf5559555);
+    DO_MIPS32_r2_s(msubu, 15, 0xffffffff, 0xf5559555, 0x00004000, 0x00007FFF, 0xffffffff, 0xd555d555);
+    DO_MIPS32_r2_s(msubu, 16, 0xffffffff, 0xd555d555, 0x00008000, 0x0000FFFF, 0xffffffff, 0x55565555);
+    DO_MIPS32_r2_s(msubu, 17, 0xffffffff, 0x55565555, 0x00010000, 0x0001FFFF, 0xfffffffd, 0x55575555);
+    DO_MIPS32_r2_s(msubu, 18, 0xfffffffd, 0x55575555, 0x00020000, 0x0003FFFF, 0xfffffff5, 0x55595555);
+    DO_MIPS32_r2_s(msubu, 19, 0xfffffff5, 0x55595555, 0x00040000, 0x0007FFFF, 0xffffffd5, 0x555d5555);
+    DO_MIPS32_r2_s(msubu, 20, 0xffffffd5, 0x555d5555, 0x00080000, 0x000FFFFF, 0xffffff55, 0x55655555);
+    DO_MIPS32_r2_s(msubu, 21, 0xffffff55, 0x55655555, 0x00100000, 0x001FFFFF, 0xfffffd55, 0x55755555);
+    DO_MIPS32_r2_s(msubu, 22, 0xfffffd55, 0x55755555, 0x00200000, 0x003FFFFF, 0xfffff555, 0x55955555);
+    DO_MIPS32_r2_s(msubu, 23, 0xfffff555, 0x55955555, 0x00400000, 0x007FFFFF, 0xffffd555, 0x55d55555);
+    DO_MIPS32_r2_s(msubu, 24, 0xffffd555, 0x55d55555, 0x00800000, 0x00FFFFFF, 0xffff5555, 0x56555555);
+    DO_MIPS32_r2_s(msubu, 25, 0xffff5555, 0x56555555, 0x01000000, 0x01FFFFFF, 0xfffd5555, 0x57555555);
+    DO_MIPS32_r2_s(msubu, 26, 0xfffd5555, 0x57555555, 0x02000000, 0x03FFFFFF, 0xfff55555, 0x59555555);
+    DO_MIPS32_r2_s(msubu, 27, 0xfff55555, 0x59555555, 0x04000000, 0x07FFFFFF, 0xffd55555, 0x5d555555);
+    DO_MIPS32_r2_s(msubu, 28, 0xffd55555, 0x5d555555, 0x08000000, 0x0FFFFFFF, 0xff555555, 0x65555555);
+    DO_MIPS32_r2_s(msubu, 29, 0xff555555, 0x65555555, 0x10000000, 0x1FFFFFFF, 0xfd555555, 0x75555555);
+    DO_MIPS32_r2_s(msubu, 30, 0xfd555555, 0x75555555, 0x20000000, 0x3FFFFFFF, 0xf5555555, 0x95555555);
+    DO_MIPS32_r2_s(msubu, 31, 0xf5555555, 0x95555555, 0x40000000, 0x7FFFFFFF, 0xd5555555, 0xd5555555);
+    DO_MIPS32_r2_s(msubu, 32, 0xd5555555, 0xd5555555, 0x80000000, 0xFFFFFFFF, 0x55555556, 0x55555555);
+    DO_MIPS32_r2_s(msubu, 33, 0x00000000, 0x00000000, 0x00000000, 0x55555555, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(msubu, 34, 0x00000000, 0x00000000, 0x55555555, 0x55555555, 0xe38e38e3, 0xc71c71c7);
+    DO_MIPS32_r2_s(msubu, 35, 0xe38e38e3, 0xc71c71c7, 0xAAAAAAAA, 0x55555555, 0xaaaaaaab, 0x55555555);
+    DO_MIPS32_r2_s(msubu, 36, 0xaaaaaaab, 0x55555555, 0xFFFFFFFF, 0x55555555, 0x55555556, 0xaaaaaaaa);
+    DO_MIPS32_r2_s(msubu, 37, 0x55555556, 0xaaaaaaaa, 0xAAAAAAAA, 0x00000000, 0x55555556, 0xaaaaaaaa);
+    DO_MIPS32_r2_s(msubu, 38, 0x55555556, 0xaaaaaaaa, 0xAAAAAAAA, 0x55555555, 0x1c71c71e, 0x38e38e38);
+    DO_MIPS32_r2_s(msubu, 39, 0x1c71c71e, 0x38e38e38, 0xAAAAAAAA, 0xAAAAAAAA, 0xaaaaaaad, 0x55555554);
+    DO_MIPS32_r2_s(msubu, 40, 0xaaaaaaad, 0x55555554, 0xAAAAAAAA, 0xFFFFFFFF, 0x00000003, 0xfffffffe);
+    DO_MIPS32_r2_s(msubu, 41, 0x00000000, 0x00000000, 0x7FFFFFFF, 0x7FFFFFFF, 0xc0000000, 0xffffffff);
+    DO_MIPS32_r2_s(msubu, 42, 0xc0000000, 0xffffffff, 0x7FFFFFFF, 0x80000000, 0x80000001, 0x7fffffff);
+    DO_MIPS32_r2_s(msubu, 43, 0x80000001, 0x7fffffff, 0x7FFFFFFF, 0xFFFFFFFF, 0x00000002, 0xfffffffe);
+    DO_MIPS32_r2_s(msubu, 44, 0x00000002, 0xfffffffe, 0x80000000, 0x7FFFFFFF, 0xc0000003, 0x7ffffffe);
+    DO_MIPS32_r2_s(msubu, 45, 0xc0000003, 0x7ffffffe, 0x80000000, 0x80000000, 0x80000003, 0x7ffffffe);
+    DO_MIPS32_r2_s(msubu, 46, 0x80000003, 0x7ffffffe, 0x80000000, 0xFFFFFFFF, 0x00000003, 0xfffffffe);
+    DO_MIPS32_r2_s(msubu, 47, 0x00000003, 0xfffffffe, 0xFFFFFFFF, 0x7FFFFFFF, 0x80000005, 0x7ffffffd);
+    DO_MIPS32_r2_s(msubu, 48, 0x80000005, 0x7ffffffd, 0xFFFFFFFF, 0x80000000, 0x00000005, 0xfffffffd);
+    DO_MIPS32_r2_s(msubu, 49, 0x00000005, 0xfffffffd, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0xfffffffc);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/mul.c b/tests/tcg/mips/user/isa/mips32/arithmatic/mul.c
new file mode 100644
index 0000000000..ab74a14545
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/mul.c
@@ -0,0 +1,78 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r(mul, 0, 0x00000000, 0x00000000, 0x00000000);
+    DO_MIPS32_r(mul, 1, 0x00000001, 0x00000001, 0x00000001);
+    DO_MIPS32_r(mul, 2, 0x00000002, 0x00000003, 0x00000006);
+    DO_MIPS32_r(mul, 3, 0x00000004, 0x00000007, 0x0000001C);
+    DO_MIPS32_r(mul, 4, 0x00000008, 0x0000000F, 0x00000078);
+    DO_MIPS32_r(mul, 5, 0x00000010, 0x0000001F, 0x000001F0);
+    DO_MIPS32_r(mul, 6, 0x00000020, 0x0000003F, 0x000007E0);
+    DO_MIPS32_r(mul, 7, 0x00000040, 0x0000007F, 0x00001FC0);
+    DO_MIPS32_r(mul, 8, 0x00000080, 0x000000FF, 0x00007F80);
+    DO_MIPS32_r(mul, 9, 0x00000100, 0x000001FF, 0x0001FF00);
+    DO_MIPS32_r(mul, 10, 0x00000200, 0x000003FF, 0x0007FE00);
+    DO_MIPS32_r(mul, 11, 0x00000400, 0x000007FF, 0x001FFC00);
+    DO_MIPS32_r(mul, 12, 0x00000800, 0x00000FFF, 0x007FF800);
+    DO_MIPS32_r(mul, 13, 0x00001000, 0x00001FFF, 0x01FFF000);
+    DO_MIPS32_r(mul, 14, 0x00002000, 0x00003FFF, 0x07FFE000);
+    DO_MIPS32_r(mul, 15, 0x00004000, 0x00007FFF, 0x1FFFC000);
+    DO_MIPS32_r(mul, 16, 0x00008000, 0x0000FFFF, 0x7FFF8000);
+    DO_MIPS32_r(mul, 17, 0x00010000, 0x0001FFFF, 0xFFFF0000);
+    DO_MIPS32_r(mul, 18, 0x00020000, 0x0003FFFF, 0xFFFE0000);
+    DO_MIPS32_r(mul, 19, 0x00040000, 0x0007FFFF, 0xFFFC0000);
+    DO_MIPS32_r(mul, 20, 0x00080000, 0x000FFFFF, 0xFFF80000);
+    DO_MIPS32_r(mul, 21, 0x00100000, 0x001FFFFF, 0xFFF00000);
+    DO_MIPS32_r(mul, 22, 0x00200000, 0x003FFFFF, 0xFFE00000);
+    DO_MIPS32_r(mul, 23, 0x00400000, 0x007FFFFF, 0xFFC00000);
+    DO_MIPS32_r(mul, 24, 0x00800000, 0x00FFFFFF, 0xFF800000);
+    DO_MIPS32_r(mul, 25, 0x01000000, 0x01FFFFFF, 0xFF000000);
+    DO_MIPS32_r(mul, 26, 0x02000000, 0x03FFFFFF, 0xFE000000);
+    DO_MIPS32_r(mul, 27, 0x04000000, 0x07FFFFFF, 0xFC000000);
+    DO_MIPS32_r(mul, 28, 0x08000000, 0x0FFFFFFF, 0xF8000000);
+    DO_MIPS32_r(mul, 29, 0x10000000, 0x1FFFFFFF, 0xF0000000);
+    DO_MIPS32_r(mul, 30, 0x20000000, 0x3FFFFFFF, 0xE0000000);
+    DO_MIPS32_r(mul, 31, 0x40000000, 0x7FFFFFFF, 0xC0000000);
+    DO_MIPS32_r(mul, 32, 0x80000000, 0xFFFFFFFF, 0x80000000);
+    DO_MIPS32_r(mul, 33, 0x00000000, 0x55555555, 0x00000000);
+    DO_MIPS32_r(mul, 34, 0x55555555, 0x55555555, 0x38E38E39);
+    DO_MIPS32_r(mul, 35, 0xAAAAAAAA, 0x55555555, 0x71C71C72);
+    DO_MIPS32_r(mul, 36, 0xFFFFFFFF, 0x55555555, 0xAAAAAAAB);
+    DO_MIPS32_r(mul, 37, 0xAAAAAAAA, 0x00000000, 0x00000000);
+    DO_MIPS32_r(mul, 38, 0xAAAAAAAA, 0x55555555, 0x71C71C72);
+    DO_MIPS32_r(mul, 39, 0xAAAAAAAA, 0xAAAAAAAA, 0xE38E38E4);
+    DO_MIPS32_r(mul, 40, 0xAAAAAAAA, 0xFFFFFFFF, 0x55555556);
+    DO_MIPS32_r(mul, 41, 0x7FFFFFFF, 0x7FFFFFFF, 0x00000001);
+    DO_MIPS32_r(mul, 42, 0x7FFFFFFF, 0x80000000, 0x80000000);
+    DO_MIPS32_r(mul, 43, 0x7FFFFFFF, 0xFFFFFFFF, 0x80000001);
+    DO_MIPS32_r(mul, 44, 0x80000000, 0x7FFFFFFF, 0x80000000);
+    DO_MIPS32_r(mul, 45, 0x80000000, 0x80000000, 0x00000000);
+    DO_MIPS32_r(mul, 46, 0x80000000, 0xFFFFFFFF, 0x80000000);
+    DO_MIPS32_r(mul, 47, 0xFFFFFFFF, 0x7FFFFFFF, 0x80000001);
+    DO_MIPS32_r(mul, 48, 0xFFFFFFFF, 0x80000000, 0x80000000);
+    DO_MIPS32_r(mul, 49, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/mult.c b/tests/tcg/mips/user/isa/mips32/arithmatic/mult.c
new file mode 100644
index 0000000000..8ac7b2c1b8
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/mult.c
@@ -0,0 +1,78 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r2_s(mult, 0, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(mult, 1, 0, 0, 0x00000001, 0x00000001, 0x00000000, 0x00000001);
+    DO_MIPS32_r2_s(mult, 2, 0, 0, 0x00000002, 0x00000003, 0x00000000, 0x00000006);
+    DO_MIPS32_r2_s(mult, 3, 0, 0, 0x00000004, 0x00000007, 0x00000000, 0x0000001C);
+    DO_MIPS32_r2_s(mult, 4, 0, 0, 0x00000008, 0x0000000F, 0x00000000, 0x00000078);
+    DO_MIPS32_r2_s(mult, 5, 0, 0, 0x00000010, 0x0000001F, 0x00000000, 0x000001F0);
+    DO_MIPS32_r2_s(mult, 6, 0, 0, 0x00000020, 0x0000003F, 0x00000000, 0x000007E0);
+    DO_MIPS32_r2_s(mult, 7, 0, 0, 0x00000040, 0x0000007F, 0x00000000, 0x00001FC0);
+    DO_MIPS32_r2_s(mult, 8, 0, 0, 0x00000080, 0x000000FF, 0x00000000, 0x00007F80);
+    DO_MIPS32_r2_s(mult, 9, 0, 0, 0x00000100, 0x000001FF, 0x00000000, 0x0001FF00);
+    DO_MIPS32_r2_s(mult, 10, 0, 0, 0x00000200, 0x000003FF, 0x00000000, 0x0007FE00);
+    DO_MIPS32_r2_s(mult, 11, 0, 0, 0x00000400, 0x000007FF, 0x00000000, 0x001FFC00);
+    DO_MIPS32_r2_s(mult, 12, 0, 0, 0x00000800, 0x00000FFF, 0x00000000, 0x007FF800);
+    DO_MIPS32_r2_s(mult, 13, 0, 0, 0x00001000, 0x00001FFF, 0x00000000, 0x01FFF000);
+    DO_MIPS32_r2_s(mult, 14, 0, 0, 0x00002000, 0x00003FFF, 0x00000000, 0x07FFE000);
+    DO_MIPS32_r2_s(mult, 15, 0, 0, 0x00004000, 0x00007FFF, 0x00000000, 0x1FFFC000);
+    DO_MIPS32_r2_s(mult, 16, 0, 0, 0x00008000, 0x0000FFFF, 0x00000000, 0x7FFF8000);
+    DO_MIPS32_r2_s(mult, 17, 0, 0, 0x00010000, 0x0001FFFF, 0x00000001, 0xFFFF0000);
+    DO_MIPS32_r2_s(mult, 18, 0, 0, 0x00020000, 0x0003FFFF, 0x00000007, 0xFFFE0000);
+    DO_MIPS32_r2_s(mult, 19, 0, 0, 0x00040000, 0x0007FFFF, 0x0000001F, 0xFFFC0000);
+    DO_MIPS32_r2_s(mult, 20, 0, 0, 0x00080000, 0x000FFFFF, 0x0000007F, 0xFFF80000);
+    DO_MIPS32_r2_s(mult, 21, 0, 0, 0x00100000, 0x001FFFFF, 0x000001FF, 0xFFF00000);
+    DO_MIPS32_r2_s(mult, 22, 0, 0, 0x00200000, 0x003FFFFF, 0x000007FF, 0xFFE00000);
+    DO_MIPS32_r2_s(mult, 23, 0, 0, 0x00400000, 0x007FFFFF, 0x00001FFF, 0xFFC00000);
+    DO_MIPS32_r2_s(mult, 24, 0, 0, 0x00800000, 0x00FFFFFF, 0x00007FFF, 0xFF800000);
+    DO_MIPS32_r2_s(mult, 25, 0, 0, 0x01000000, 0x01FFFFFF, 0x0001FFFF, 0xFF000000);
+    DO_MIPS32_r2_s(mult, 26, 0, 0, 0x02000000, 0x03FFFFFF, 0x0007FFFF, 0xFE000000);
+    DO_MIPS32_r2_s(mult, 27, 0, 0, 0x04000000, 0x07FFFFFF, 0x001FFFFF, 0xFC000000);
+    DO_MIPS32_r2_s(mult, 28, 0, 0, 0x08000000, 0x0FFFFFFF, 0x007FFFFF, 0xF8000000);
+    DO_MIPS32_r2_s(mult, 29, 0, 0, 0x10000000, 0x1FFFFFFF, 0x01FFFFFF, 0xF0000000);
+    DO_MIPS32_r2_s(mult, 30, 0, 0, 0x20000000, 0x3FFFFFFF, 0x07FFFFFF, 0xE0000000);
+    DO_MIPS32_r2_s(mult, 31, 0, 0, 0x40000000, 0x7FFFFFFF, 0x1FFFFFFF, 0xC0000000);
+    DO_MIPS32_r2_s(mult, 32, 0, 0, 0x80000000, 0xFFFFFFFF, 0x00000000, 0x80000000);
+    DO_MIPS32_r2_s(mult, 33, 0, 0, 0x00000000, 0x55555555, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(mult, 34, 0, 0, 0x55555555, 0x55555555, 0x1C71C71C, 0x38E38E39);
+    DO_MIPS32_r2_s(mult, 35, 0, 0, 0xAAAAAAAA, 0x55555555, 0xE38E38E3, 0x71C71C72);
+    DO_MIPS32_r2_s(mult, 36, 0, 0, 0xFFFFFFFF, 0x55555555, 0xFFFFFFFF, 0xAAAAAAAB);
+    DO_MIPS32_r2_s(mult, 37, 0, 0, 0xAAAAAAAA, 0x00000000, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(mult, 38, 0, 0, 0xAAAAAAAA, 0x55555555, 0xE38E38E3, 0x71C71C72);
+    DO_MIPS32_r2_s(mult, 39, 0, 0, 0xAAAAAAAA, 0xAAAAAAAA, 0x1C71C71C, 0xE38E38E4);
+    DO_MIPS32_r2_s(mult, 40, 0, 0, 0xAAAAAAAA, 0xFFFFFFFF, 0x00000000, 0x55555556);
+    DO_MIPS32_r2_s(mult, 41, 0, 0, 0x7FFFFFFF, 0x7FFFFFFF, 0x3FFFFFFF, 0x00000001);
+    DO_MIPS32_r2_s(mult, 42, 0, 0, 0x7FFFFFFF, 0x80000000, 0xC0000000, 0x80000000);
+    DO_MIPS32_r2_s(mult, 43, 0, 0, 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x80000001);
+    DO_MIPS32_r2_s(mult, 44, 0, 0, 0x80000000, 0x7FFFFFFF, 0xC0000000, 0x80000000);
+    DO_MIPS32_r2_s(mult, 45, 0, 0, 0x80000000, 0x80000000, 0x40000000, 0x00000000);
+    DO_MIPS32_r2_s(mult, 46, 0, 0, 0x80000000, 0xFFFFFFFF, 0x00000000, 0x80000000);
+    DO_MIPS32_r2_s(mult, 47, 0, 0, 0xFFFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF, 0x80000001);
+    DO_MIPS32_r2_s(mult, 48, 0, 0, 0xFFFFFFFF, 0x80000000, 0x00000000, 0x80000000);
+    DO_MIPS32_r2_s(mult, 49, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000001);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/multu.c b/tests/tcg/mips/user/isa/mips32/arithmatic/multu.c
new file mode 100644
index 0000000000..eeafbd2d50
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/multu.c
@@ -0,0 +1,78 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r2_s(multu, 0, 0, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(multu, 1, 0, 0, 0x00000001, 0x00000001, 0x00000000, 0x00000001);
+    DO_MIPS32_r2_s(multu, 2, 0, 0, 0x00000002, 0x00000003, 0x00000000, 0x00000006);
+    DO_MIPS32_r2_s(multu, 3, 0, 0, 0x00000004, 0x00000007, 0x00000000, 0x0000001C);
+    DO_MIPS32_r2_s(multu, 4, 0, 0, 0x00000008, 0x0000000F, 0x00000000, 0x00000078);
+    DO_MIPS32_r2_s(multu, 5, 0, 0, 0x00000010, 0x0000001F, 0x00000000, 0x000001F0);
+    DO_MIPS32_r2_s(multu, 6, 0, 0, 0x00000020, 0x0000003F, 0x00000000, 0x000007E0);
+    DO_MIPS32_r2_s(multu, 7, 0, 0, 0x00000040, 0x0000007F, 0x00000000, 0x00001FC0);
+    DO_MIPS32_r2_s(multu, 8, 0, 0, 0x00000080, 0x000000FF, 0x00000000, 0x00007F80);
+    DO_MIPS32_r2_s(multu, 9, 0, 0, 0x00000100, 0x000001FF, 0x00000000, 0x0001FF00);
+    DO_MIPS32_r2_s(multu, 10, 0, 0, 0x00000200, 0x000003FF, 0x00000000, 0x0007FE00);
+    DO_MIPS32_r2_s(multu, 11, 0, 0, 0x00000400, 0x000007FF, 0x00000000, 0x001FFC00);
+    DO_MIPS32_r2_s(multu, 12, 0, 0, 0x00000800, 0x00000FFF, 0x00000000, 0x007FF800);
+    DO_MIPS32_r2_s(multu, 13, 0, 0, 0x00001000, 0x00001FFF, 0x00000000, 0x01FFF000);
+    DO_MIPS32_r2_s(multu, 14, 0, 0, 0x00002000, 0x00003FFF, 0x00000000, 0x07FFE000);
+    DO_MIPS32_r2_s(multu, 15, 0, 0, 0x00004000, 0x00007FFF, 0x00000000, 0x1FFFC000);
+    DO_MIPS32_r2_s(multu, 16, 0, 0, 0x00008000, 0x0000FFFF, 0x00000000, 0x7FFF8000);
+    DO_MIPS32_r2_s(multu, 17, 0, 0, 0x00010000, 0x0001FFFF, 0x00000001, 0xFFFF0000);
+    DO_MIPS32_r2_s(multu, 18, 0, 0, 0x00020000, 0x0003FFFF, 0x00000007, 0xFFFE0000);
+    DO_MIPS32_r2_s(multu, 19, 0, 0, 0x00040000, 0x0007FFFF, 0x0000001F, 0xFFFC0000);
+    DO_MIPS32_r2_s(multu, 20, 0, 0, 0x00080000, 0x000FFFFF, 0x0000007F, 0xFFF80000);
+    DO_MIPS32_r2_s(multu, 21, 0, 0, 0x00100000, 0x001FFFFF, 0x000001FF, 0xFFF00000);
+    DO_MIPS32_r2_s(multu, 22, 0, 0, 0x00200000, 0x003FFFFF, 0x000007FF, 0xFFE00000);
+    DO_MIPS32_r2_s(multu, 23, 0, 0, 0x00400000, 0x007FFFFF, 0x00001FFF, 0xFFC00000);
+    DO_MIPS32_r2_s(multu, 24, 0, 0, 0x00800000, 0x00FFFFFF, 0x00007FFF, 0xFF800000);
+    DO_MIPS32_r2_s(multu, 25, 0, 0, 0x01000000, 0x01FFFFFF, 0x0001FFFF, 0xFF000000);
+    DO_MIPS32_r2_s(multu, 26, 0, 0, 0x02000000, 0x03FFFFFF, 0x0007FFFF, 0xFE000000);
+    DO_MIPS32_r2_s(multu, 27, 0, 0, 0x04000000, 0x07FFFFFF, 0x001FFFFF, 0xFC000000);
+    DO_MIPS32_r2_s(multu, 28, 0, 0, 0x08000000, 0x0FFFFFFF, 0x007FFFFF, 0xF8000000);
+    DO_MIPS32_r2_s(multu, 29, 0, 0, 0x10000000, 0x1FFFFFFF, 0x01FFFFFF, 0xF0000000);
+    DO_MIPS32_r2_s(multu, 30, 0, 0, 0x20000000, 0x3FFFFFFF, 0x07FFFFFF, 0xE0000000);
+    DO_MIPS32_r2_s(multu, 31, 0, 0, 0x40000000, 0x7FFFFFFF, 0x1FFFFFFF, 0xC0000000);
+    DO_MIPS32_r2_s(multu, 32, 0, 0, 0x80000000, 0xFFFFFFFF, 0x7FFFFFFF, 0x80000000);
+    DO_MIPS32_r2_s(multu, 33, 0, 0, 0x00000000, 0x55555555, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(multu, 34, 0, 0, 0x55555555, 0x55555555, 0x1C71C71C, 0x38E38E39);
+    DO_MIPS32_r2_s(multu, 35, 0, 0, 0xAAAAAAAA, 0x55555555, 0x38E38E38, 0x71C71C72);
+    DO_MIPS32_r2_s(multu, 36, 0, 0, 0xFFFFFFFF, 0x55555555, 0x55555554, 0xAAAAAAAB);
+    DO_MIPS32_r2_s(multu, 37, 0, 0, 0xAAAAAAAA, 0x00000000, 0x00000000, 0x00000000);
+    DO_MIPS32_r2_s(multu, 38, 0, 0, 0xAAAAAAAA, 0x55555555, 0x38E38E38, 0x71C71C72);
+    DO_MIPS32_r2_s(multu, 39, 0, 0, 0xAAAAAAAA, 0xAAAAAAAA, 0x71C71C70, 0xE38E38E4);
+    DO_MIPS32_r2_s(multu, 40, 0, 0, 0xAAAAAAAA, 0xFFFFFFFF, 0xAAAAAAA9, 0x55555556);
+    DO_MIPS32_r2_s(multu, 41, 0, 0, 0x7FFFFFFF, 0x7FFFFFFF, 0x3FFFFFFF, 0x00000001);
+    DO_MIPS32_r2_s(multu, 42, 0, 0, 0x7FFFFFFF, 0x80000000, 0x3FFFFFFF, 0x80000000);
+    DO_MIPS32_r2_s(multu, 43, 0, 0, 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFE, 0x80000001);
+    DO_MIPS32_r2_s(multu, 44, 0, 0, 0x80000000, 0x7FFFFFFF, 0x3FFFFFFF, 0x80000000);
+    DO_MIPS32_r2_s(multu, 45, 0, 0, 0x80000000, 0x80000000, 0x40000000, 0x00000000);
+    DO_MIPS32_r2_s(multu, 46, 0, 0, 0x80000000, 0xFFFFFFFF, 0x7FFFFFFF, 0x80000000);
+    DO_MIPS32_r2_s(multu, 47, 0, 0, 0xFFFFFFFF, 0x7FFFFFFF, 0x7FFFFFFE, 0x80000001);
+    DO_MIPS32_r2_s(multu, 48, 0, 0, 0xFFFFFFFF, 0x80000000, 0x7FFFFFFF, 0x80000000);
+    DO_MIPS32_r2_s(multu, 49, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/slt.c b/tests/tcg/mips/user/isa/mips32/arithmatic/slt.c
new file mode 100644
index 0000000000..74f22c365e
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/slt.c
@@ -0,0 +1,61 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r(slt, 0, 0x00000000, 0x00000000, 0);
+    DO_MIPS32_r(slt, 1, 0x00000001, 0x00000001, 0);
+    DO_MIPS32_r(slt, 2, 0x00000002, 0x00000003, 1);
+    DO_MIPS32_r(slt, 3, 0x00000005, 0x00000007, 1);
+    DO_MIPS32_r(slt, 4, 0x0000000B, 0x0000000F, 1);
+    DO_MIPS32_r(slt, 5, 0x00000017, 0x0000001F, 1);
+    DO_MIPS32_r(slt, 6, 0x0000002F, 0x0000003F, 1);
+    DO_MIPS32_r(slt, 7, 0x0000005F, 0x0000007F, 1);
+    DO_MIPS32_r(slt, 8, 0x000000BF, 0x000000FF, 1);
+    DO_MIPS32_r(slt, 9, 0x0000017F, 0x000001FF, 1);
+    DO_MIPS32_r(slt, 10, 0x000002FF, 0x000003FF, 1);
+    DO_MIPS32_r(slt, 11, 0x000005FF, 0x000007FF, 1);
+    DO_MIPS32_r(slt, 12, 0x00000BFF, 0x00000FFF, 1);
+    DO_MIPS32_r(slt, 13, 0x000017FF, 0x00001FFF, 1);
+    DO_MIPS32_r(slt, 14, 0x00002FFF, 0x00003FFF, 1);
+    DO_MIPS32_r(slt, 15, 0x00005FFF, 0x00007FFF, 1);
+    DO_MIPS32_r(slt, 16, 0x0000BFFF, 0x0000FFFF, 1);
+    DO_MIPS32_r(slt, 17, 0x00017FFF, 0x0001FFFF, 1);
+    DO_MIPS32_r(slt, 18, 0x0002FFFF, 0x0003FFFF, 1);
+    DO_MIPS32_r(slt, 19, 0x0005FFFF, 0x0007FFFF, 1);
+    DO_MIPS32_r(slt, 20, 0x000BFFFF, 0x000FFFFF, 1);
+    DO_MIPS32_r(slt, 21, 0x0017FFFF, 0x001FFFFF, 1);
+    DO_MIPS32_r(slt, 22, 0x002FFFFF, 0x003FFFFF, 1);
+    DO_MIPS32_r(slt, 23, 0x005FFFFF, 0x007FFFFF, 1);
+    DO_MIPS32_r(slt, 24, 0x00BFFFFF, 0x00FFFFFF, 1);
+    DO_MIPS32_r(slt, 25, 0x017FFFFF, 0x01FFFFFF, 1);
+    DO_MIPS32_r(slt, 26, 0x02FFFFFF, 0x03FFFFFF, 1);
+    DO_MIPS32_r(slt, 27, 0x05FFFFFF, 0x07FFFFFF, 1);
+    DO_MIPS32_r(slt, 28, 0x0BFFFFFF, 0x0FFFFFFF, 1);
+    DO_MIPS32_r(slt, 29, 0x17FFFFFF, 0x1FFFFFFF, 1);
+    DO_MIPS32_r(slt, 30, 0x2FFFFFFF, 0x3FFFFFFF, 1);
+    DO_MIPS32_r(slt, 31, 0x5FFFFFFF, 0x7FFFFFFF, 1);
+    DO_MIPS32_r(slt, 32, 0xBFFFFFFF, 0xFFFFFFFF, 1);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/slti.c b/tests/tcg/mips/user/isa/mips32/arithmatic/slti.c
new file mode 100644
index 0000000000..823af3e4d4
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/slti.c
@@ -0,0 +1,48 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_i(slti, 0, 0x0000, 0x00000000, 0);
+    DO_MIPS32_i(slti, 1, 0x0001, 0x00000001, 0);
+    DO_MIPS32_i(slti, 2, 0x0003, 0x00000002, 1);
+    DO_MIPS32_i(slti, 3, 0x0007, 0x00000005, 1);
+    DO_MIPS32_i(slti, 4, 0x000F, 0x0000000B, 1);
+    DO_MIPS32_i(slti, 5, 0x001F, 0x00000017, 1);
+    DO_MIPS32_i(slti, 6, 0x003F, 0x0000002F, 1);
+    DO_MIPS32_i(slti, 7, 0x007F, 0x0000005F, 1);
+    DO_MIPS32_i(slti, 8, 0x00FF, 0x000000BF, 1);
+    DO_MIPS32_i(slti, 9, 0x01FF, 0x0000017F, 1);
+    DO_MIPS32_i(slti, 10, 0x03FF, 0x000002FF, 1);
+    DO_MIPS32_i(slti, 11, 0x07FF, 0x000005FF, 1);
+    DO_MIPS32_i(slti, 12, 0x0FFF, 0x00000BFF, 1);
+    DO_MIPS32_i(slti, 13, 0x1FFF, 0x000017FF, 1);
+    DO_MIPS32_i(slti, 14, 0x3FFF, 0x00002FFF, 1);
+    DO_MIPS32_i(slti, 15, 0x7FFF, 0x00005FFF, 1);
+    DO_MIPS32_i(slti, 16, 0xFFFF, 0x0000BFFF, 0);
+    DO_MIPS32_i(slti, 17, 0xFFFF, 0x7FFFFFFF, 0);
+    DO_MIPS32_i(slti, 18, 0x8000, 0x7FFFFFFF, 0);
+    DO_MIPS32_i(slti, 19, 0x5555, 0x00000000, 1);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/sltiu.c b/tests/tcg/mips/user/isa/mips32/arithmatic/sltiu.c
new file mode 100644
index 0000000000..5644d4d1c1
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/sltiu.c
@@ -0,0 +1,48 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_i(sltiu, 0, 0x0000, 0x00000000, 0);
+    DO_MIPS32_i(sltiu, 1, 0x0001, 0x00000001, 0);
+    DO_MIPS32_i(sltiu, 2, 0x0003, 0x00000002, 1);
+    DO_MIPS32_i(sltiu, 3, 0x0007, 0x00000005, 1);
+    DO_MIPS32_i(sltiu, 4, 0x000F, 0x0000000B, 1);
+    DO_MIPS32_i(sltiu, 5, 0x001F, 0x00000017, 1);
+    DO_MIPS32_i(sltiu, 6, 0x003F, 0x0000002F, 1);
+    DO_MIPS32_i(sltiu, 7, 0x007F, 0x0000005F, 1);
+    DO_MIPS32_i(sltiu, 8, 0x00FF, 0x000000BF, 1);
+    DO_MIPS32_i(sltiu, 9, 0x01FF, 0x0000017F, 1);
+    DO_MIPS32_i(sltiu, 10, 0x03FF, 0x000002FF, 1);
+    DO_MIPS32_i(sltiu, 11, 0x07FF, 0x000005FF, 1);
+    DO_MIPS32_i(sltiu, 12, 0x0FFF, 0x00000BFF, 1);
+    DO_MIPS32_i(sltiu, 13, 0x1FFF, 0x000017FF, 1);
+    DO_MIPS32_i(sltiu, 14, 0x3FFF, 0x00002FFF, 1);
+    DO_MIPS32_i(sltiu, 15, 0x7FFF, 0x00005FFF, 1);
+    DO_MIPS32_i(sltiu, 16, 0xFFFF, 0x0000BFFF, 1);
+    DO_MIPS32_i(sltiu, 17, 0x5555, 0x00000000, 1);
+    DO_MIPS32_i(sltiu, 18, 0xFFFF, 0x7FFFFFFF, 1);
+    DO_MIPS32_i(sltiu, 19, 0x8000, 0x7FFFFFFF, 1);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/sltu.c b/tests/tcg/mips/user/isa/mips32/arithmatic/sltu.c
new file mode 100644
index 0000000000..bba246626e
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/sltu.c
@@ -0,0 +1,61 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r(sltu, 0, 0x00000000, 0x00000000, 0);
+    DO_MIPS32_r(sltu, 1, 0x00000001, 0x00000001, 0);
+    DO_MIPS32_r(sltu, 2, 0x00000002, 0x00000003, 1);
+    DO_MIPS32_r(sltu, 3, 0x00000005, 0x00000007, 1);
+    DO_MIPS32_r(sltu, 4, 0x0000000B, 0x0000000F, 1);
+    DO_MIPS32_r(sltu, 5, 0x00000017, 0x0000001F, 1);
+    DO_MIPS32_r(sltu, 6, 0x0000002F, 0x0000003F, 1);
+    DO_MIPS32_r(sltu, 7, 0x0000005F, 0x0000007F, 1);
+    DO_MIPS32_r(sltu, 8, 0x000000BF, 0x000000FF, 1);
+    DO_MIPS32_r(sltu, 9, 0x0000017F, 0x000001FF, 1);
+    DO_MIPS32_r(sltu, 10, 0x000002FF, 0x000003FF, 1);
+    DO_MIPS32_r(sltu, 11, 0x000005FF, 0x000007FF, 1);
+    DO_MIPS32_r(sltu, 12, 0x00000BFF, 0x00000FFF, 1);
+    DO_MIPS32_r(sltu, 13, 0x000017FF, 0x00001FFF, 1);
+    DO_MIPS32_r(sltu, 14, 0x00002FFF, 0x00003FFF, 1);
+    DO_MIPS32_r(sltu, 15, 0x00005FFF, 0x00007FFF, 1);
+    DO_MIPS32_r(sltu, 16, 0x0000BFFF, 0x0000FFFF, 1);
+    DO_MIPS32_r(sltu, 17, 0x00017FFF, 0x0001FFFF, 1);
+    DO_MIPS32_r(sltu, 18, 0x0002FFFF, 0x0003FFFF, 1);
+    DO_MIPS32_r(sltu, 19, 0x0005FFFF, 0x0007FFFF, 1);
+    DO_MIPS32_r(sltu, 20, 0x000BFFFF, 0x000FFFFF, 1);
+    DO_MIPS32_r(sltu, 21, 0x0017FFFF, 0x001FFFFF, 1);
+    DO_MIPS32_r(sltu, 22, 0x002FFFFF, 0x003FFFFF, 1);
+    DO_MIPS32_r(sltu, 23, 0x005FFFFF, 0x007FFFFF, 1);
+    DO_MIPS32_r(sltu, 24, 0x00BFFFFF, 0x00FFFFFF, 1);
+    DO_MIPS32_r(sltu, 25, 0x017FFFFF, 0x01FFFFFF, 1);
+    DO_MIPS32_r(sltu, 26, 0x02FFFFFF, 0x03FFFFFF, 1);
+    DO_MIPS32_r(sltu, 27, 0x05FFFFFF, 0x07FFFFFF, 1);
+    DO_MIPS32_r(sltu, 28, 0x0BFFFFFF, 0x0FFFFFFF, 1);
+    DO_MIPS32_r(sltu, 29, 0x17FFFFFF, 0x1FFFFFFF, 1);
+    DO_MIPS32_r(sltu, 30, 0x2FFFFFFF, 0x3FFFFFFF, 1);
+    DO_MIPS32_r(sltu, 31, 0x5FFFFFFF, 0x7FFFFFFF, 1);
+    DO_MIPS32_r(sltu, 32, 0xBFFFFFFF, 0xFFFFFFFF, 1);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/sub.c b/tests/tcg/mips/user/isa/mips32/arithmatic/sub.c
new file mode 100644
index 0000000000..86f747c2e7
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/sub.c
@@ -0,0 +1,104 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r(sub, 0, 0x00000000, 0x00000000, 0x00000000);
+    DO_MIPS32_r(sub, 1, 0x00000001, 0x00000001, 0x00000000);
+    DO_MIPS32_r(sub, 2, 0x00000002, 0x00000003, 0xFFFFFFFF);
+    DO_MIPS32_r(sub, 3, 0x00000004, 0x00000006, 0xFFFFFFFE);
+    DO_MIPS32_r(sub, 4, 0x00000008, 0x0000000C, 0xFFFFFFFC);
+    DO_MIPS32_r(sub, 5, 0x00000010, 0x00000018, 0xFFFFFFF8);
+    DO_MIPS32_r(sub, 6, 0x00000020, 0x00000030, 0xFFFFFFF0);
+    DO_MIPS32_r(sub, 7, 0x00000040, 0x00000060, 0xFFFFFFE0);
+    DO_MIPS32_r(sub, 8, 0x00000080, 0x000000C0, 0xFFFFFFC0);
+    DO_MIPS32_r(sub, 9, 0x00000100, 0x00000180, 0xFFFFFF80);
+    DO_MIPS32_r(sub, 10, 0x00000200, 0x00000300, 0xFFFFFF00);
+    DO_MIPS32_r(sub, 11, 0x00000400, 0x00000600, 0xFFFFFE00);
+    DO_MIPS32_r(sub, 12, 0x00000800, 0x00000C00, 0xFFFFFC00);
+    DO_MIPS32_r(sub, 13, 0x00001000, 0x00001800, 0xFFFFF800);
+    DO_MIPS32_r(sub, 14, 0x00002000, 0x00003000, 0xFFFFF000);
+    DO_MIPS32_r(sub, 15, 0x00004000, 0x00006000, 0xFFFFE000);
+    DO_MIPS32_r(sub, 16, 0x00008000, 0x0000C000, 0xFFFFC000);
+    DO_MIPS32_r(sub, 17, 0x00010000, 0x00018000, 0xFFFF8000);
+    DO_MIPS32_r(sub, 18, 0x00020000, 0x00030000, 0xFFFF0000);
+    DO_MIPS32_r(sub, 19, 0x00040000, 0x00060000, 0xFFFE0000);
+    DO_MIPS32_r(sub, 20, 0x00080000, 0x000C0000, 0xFFFC0000);
+    DO_MIPS32_r(sub, 21, 0x00100000, 0x00180000, 0xFFF80000);
+    DO_MIPS32_r(sub, 22, 0x00200000, 0x00300000, 0xFFF00000);
+    DO_MIPS32_r(sub, 23, 0x00400000, 0x00600000, 0xFFE00000);
+    DO_MIPS32_r(sub, 24, 0x00800000, 0x00C00000, 0xFFC00000);
+    DO_MIPS32_r(sub, 25, 0x01000000, 0x01800000, 0xFF800000);
+    DO_MIPS32_r(sub, 26, 0x02000000, 0x03000000, 0xFF000000);
+    DO_MIPS32_r(sub, 27, 0x04000000, 0x06000000, 0xFE000000);
+    DO_MIPS32_r(sub, 28, 0x08000000, 0x0C000000, 0xFC000000);
+    DO_MIPS32_r(sub, 29, 0x10000000, 0x18000000, 0xF8000000);
+    DO_MIPS32_r(sub, 30, 0x20000000, 0x30000000, 0xF0000000);
+    DO_MIPS32_r(sub, 31, 0x40000000, 0x60000000, 0xE0000000);
+    DO_MIPS32_r(sub, 32, 0x80000000, 0xC0000000, 0xC0000000);
+    DO_MIPS32_r(sub, 33, 0x00000000, 0x80000000, 0x80000000);
+    DO_MIPS32_r(sub, 34, 0x80000001, 0x80000001, 0x00000000);
+    DO_MIPS32_r(sub, 35, 0xC0000003, 0x40000002, 0x80000001);
+    DO_MIPS32_r(sub, 36, 0xE0000007, 0x20000004, 0xC0000003);
+    DO_MIPS32_r(sub, 37, 0xF000000F, 0x10000008, 0xE0000007);
+    DO_MIPS32_r(sub, 38, 0xF800001F, 0x08000010, 0xF000000F);
+    DO_MIPS32_r(sub, 39, 0xFC00003F, 0x04000020, 0xF800001F);
+    DO_MIPS32_r(sub, 40, 0xFE00007F, 0x02000040, 0xFC00003F);
+    DO_MIPS32_r(sub, 41, 0xFF0000FF, 0x01000080, 0xFE00007F);
+    DO_MIPS32_r(sub, 42, 0xFF8001FF, 0x00800100, 0xFF0000FF);
+    DO_MIPS32_r(sub, 43, 0xFFC003FF, 0x00400200, 0xFF8001FF);
+    DO_MIPS32_r(sub, 44, 0xFFE007FF, 0x00200400, 0xFFC003FF);
+    DO_MIPS32_r(sub, 45, 0xFFF00FFF, 0x00100800, 0xFFE007FF);
+    DO_MIPS32_r(sub, 46, 0xFFF81FFF, 0x00081000, 0xFFF00FFF);
+    DO_MIPS32_r(sub, 47, 0xFFFC3FFF, 0x00042000, 0xFFF81FFF);
+    DO_MIPS32_r(sub, 48, 0xFFFE7FFF, 0x00024000, 0xFFFC3FFF);
+    DO_MIPS32_r(sub, 49, 0xFFFFFFFF, 0x00018000, 0xFFFE7FFF);
+    DO_MIPS32_r(sub, 50, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF);
+    DO_MIPS32_r(sub, 51, 0xFFFFFFFF, 0x00018000, 0xFFFE7FFF);
+    DO_MIPS32_r(sub, 52, 0xFFFE7FFF, 0x0003C000, 0xFFFABFFF);
+    DO_MIPS32_r(sub, 53, 0xFFFC3FFF, 0x0007E000, 0xFFF45FFF);
+    DO_MIPS32_r(sub, 54, 0xFFF81FFF, 0x000FF000, 0xFFE82FFF);
+    DO_MIPS32_r(sub, 55, 0xFFF00FFF, 0x001FF800, 0xFFD017FF);
+    DO_MIPS32_r(sub, 56, 0xFFE007FF, 0x003FFC00, 0xFFA00BFF);
+    DO_MIPS32_r(sub, 57, 0xFFC003FF, 0x007FFE00, 0xFF4005FF);
+    DO_MIPS32_r(sub, 58, 0xFF8001FF, 0x00FFFF00, 0xFE8002FF);
+    DO_MIPS32_r(sub, 59, 0xFF0000FF, 0x01FFFF80, 0xFD00017F);
+    DO_MIPS32_r(sub, 60, 0xFE00007F, 0x03FFFFC0, 0xFA0000BF);
+    DO_MIPS32_r(sub, 61, 0xFC00003F, 0x07FFFFE0, 0xF400005F);
+    DO_MIPS32_r(sub, 62, 0xF800001F, 0x0FFFFFF0, 0xE800002F);
+    DO_MIPS32_r(sub, 63, 0xF000000F, 0x1FFFFFF8, 0xD0000017);
+    DO_MIPS32_r(sub, 64, 0xE0000007, 0x3FFFFFFC, 0xA000000B);
+    DO_MIPS32_r(sub, 65, 0xC0000003, 0x7FFFFFFE, 0x40000005);
+    DO_MIPS32_r(sub, 66, 0x80000001, 0xFFFFFFFF, 0x80000002);
+    DO_MIPS32_r(sub, 67, 0x00000000, 0xFFFFFFFF, 0x00000001);
+    DO_MIPS32_r(sub, 68, 0x00000000, 0x55555555, 0xAAAAAAAB);
+    DO_MIPS32_r(sub, 69, 0x55555555, 0x55555555, 0x00000000);
+    DO_MIPS32_r(sub, 70, 0xAAAAAAAA, 0x15555555, 0x95555555);
+    DO_MIPS32_r(sub, 71, 0xFFFFFFFF, 0x55555555, 0xAAAAAAAA);
+    DO_MIPS32_r(sub, 72, 0xAAAAAAAA, 0x00000000, 0xAAAAAAAA);
+    DO_MIPS32_r(sub, 73, 0xAAAAAAAA, 0x15555555, 0x95555555);
+    DO_MIPS32_r(sub, 74, 0xAAAAAAAA, 0xAAAAAAAA, 0x00000000);
+    DO_MIPS32_r(sub, 75, 0xAAAAAAAA, 0xFFFFFFFF, 0xAAAAAAAB);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips32/arithmatic/subu.c b/tests/tcg/mips/user/isa/mips32/arithmatic/subu.c
new file mode 100644
index 0000000000..fe1df6a71e
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips32/arithmatic/subu.c
@@ -0,0 +1,108 @@
+/*
+ * MIPS instruction test case
+ *
+ *  Copyright (c) 2022 Jiaxun Yang
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/test_utils_32.h"
+
+int main(void)
+{
+    int ret = 0;
+    int pass_count = 0;
+    int fail_count = 0;
+
+    DO_MIPS32_r(subu, 0, 0x00000000, 0x00000000, 0x00000000);
+    DO_MIPS32_r(subu, 1, 0x00000001, 0x00000001, 0x00000000);
+    DO_MIPS32_r(subu, 2, 0x00000002, 0x00000003, 0xFFFFFFFF);
+    DO_MIPS32_r(subu, 3, 0x00000004, 0x00000006, 0xFFFFFFFE);
+    DO_MIPS32_r(subu, 4, 0x00000008, 0x0000000C, 0xFFFFFFFC);
+    DO_MIPS32_r(subu, 5, 0x00000010, 0x00000018, 0xFFFFFFF8);
+    DO_MIPS32_r(subu, 6, 0x00000020, 0x00000030, 0xFFFFFFF0);
+    DO_MIPS32_r(subu, 7, 0x00000040, 0x00000060, 0xFFFFFFE0);
+    DO_MIPS32_r(subu, 8, 0x00000080, 0x000000C0, 0xFFFFFFC0);
+    DO_MIPS32_r(subu, 9, 0x00000100, 0x00000180, 0xFFFFFF80);
+    DO_MIPS32_r(subu, 10, 0x00000200, 0x00000300, 0xFFFFFF00);
+    DO_MIPS32_r(subu, 11, 0x00000400, 0x00000600, 0xFFFFFE00);
+    DO_MIPS32_r(subu, 12, 0x00000800, 0x00000C00, 0xFFFFFC00);
+    DO_MIPS32_r(subu, 13, 0x00001000, 0x00001800, 0xFFFFF800);
+    DO_MIPS32_r(subu, 14, 0x00002000, 0x00003000, 0xFFFFF000);
+    DO_MIPS32_r(subu, 15, 0x00004000, 0x00006000, 0xFFFFE000);
+    DO_MIPS32_r(subu, 16, 0x00008000, 0x0000C000, 0xFFFFC000);
+    DO_MIPS32_r(subu, 17, 0x00010000, 0x00018000, 0xFFFF8000);
+    DO_MIPS32_r(subu, 18, 0x00020000, 0x00030000, 0xFFFF0000);
+    DO_MIPS32_r(subu, 19, 0x00040000, 0x00060000, 0xFFFE0000);
+    DO_MIPS32_r(subu, 20, 0x00080000, 0x000C0000, 0xFFFC0000);
+    DO_MIPS32_r(subu, 21, 0x00100000, 0x00180000, 0xFFF80000);
+    DO_MIPS32_r(subu, 22, 0x00200000, 0x00300000, 0xFFF00000);
+    DO_MIPS32_r(subu, 23, 0x00400000, 0x00600000, 0xFFE00000);
+    DO_MIPS32_r(subu, 24, 0x00800000, 0x00C00000, 0xFFC00000);
+    DO_MIPS32_r(subu, 25, 0x01000000, 0x01800000, 0xFF800000);
+    DO_MIPS32_r(subu, 26, 0x02000000, 0x03000000, 0xFF000000);
+    DO_MIPS32_r(subu, 27, 0x04000000, 0x06000000, 0xFE000000);
+    DO_MIPS32_r(subu, 28, 0x08000000, 0x0C000000, 0xFC000000);
+    DO_MIPS32_r(subu, 29, 0x10000000, 0x18000000, 0xF8000000);
+    DO_MIPS32_r(subu, 30, 0x20000000, 0x30000000, 0xF0000000);
+    DO_MIPS32_r(subu, 31, 0x40000000, 0x60000000, 0xE0000000);
+    DO_MIPS32_r(subu, 32, 0x80000000, 0xC0000000, 0xC0000000);
+    DO_MIPS32_r(subu, 33, 0x00000000, 0x80000000, 0x80000000);
+    DO_MIPS32_r(subu, 34, 0x80000001, 0x80000001, 0x00000000);
+    DO_MIPS32_r(subu, 35, 0xC0000003, 0x40000002, 0x80000001);
+    DO_MIPS32_r(subu, 36, 0xE0000007, 0x20000004, 0xC0000003);
+    DO_MIPS32_r(subu, 37, 0xF000000F, 0x10000008, 0xE0000007);
+    DO_MIPS32_r(subu, 38, 0xF800001F, 0x08000010, 0xF000000F);
+    DO_MIPS32_r(subu, 39, 0xFC00003F, 0x04000020, 0xF800001F);
+    DO_MIPS32_r(subu, 40, 0xFE00007F, 0x02000040, 0xFC00003F);
+    DO_MIPS32_r(subu, 41, 0xFF0000FF, 0x01000080, 0xFE00007F);
+    DO_MIPS32_r(subu, 42, 0xFF8001FF, 0x00800100, 0xFF0000FF);
+    DO_MIPS32_r(subu, 43, 0xFFC003FF, 0x00400200, 0xFF8001FF);
+    DO_MIPS32_r(subu, 44, 0xFFE007FF, 0x00200400, 0xFFC003FF);
+    DO_MIPS32_r(subu, 45, 0xFFF00FFF, 0x00100800, 0xFFE007FF);
+    DO_MIPS32_r(subu, 46, 0xFFF81FFF, 0x00081000, 0xFFF00FFF);
+    DO_MIPS32_r(subu, 47, 0xFFFC3FFF, 0x00042000, 0xFFF81FFF);
+    DO_MIPS32_r(subu, 48, 0xFFFE7FFF, 0x00024000, 0xFFFC3FFF);
+    DO_MIPS32_r(subu, 49, 0xFFFFFFFF, 0x00018000, 0xFFFE7FFF);
+    DO_MIPS32_r(subu, 50, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF);
+    DO_MIPS32_r(subu, 51, 0xFFFFFFFF, 0x00018000, 0xFFFE7FFF);
+    DO_MIPS32_r(subu, 52, 0xFFFE7FFF, 0x0003C000, 0xFFFABFFF);
+    DO_MIPS32_r(subu, 53, 0xFFFC3FFF, 0x0007E000, 0xFFF45FFF);
+    DO_MIPS32_r(subu, 54, 0xFFF81FFF, 0x000FF000, 0xFFE82FFF);
+    DO_MIPS32_r(subu, 55, 0xFFF00FFF, 0x001FF800, 0xFFD017FF);
+    DO_MIPS32_r(subu, 56, 0xFFE007FF, 0x003FFC00, 0xFFA00BFF);
+    DO_MIPS32_r(subu, 57, 0xFFC003FF, 0x007FFE00, 0xFF4005FF);
+    DO_MIPS32_r(subu, 58, 0xFF8001FF, 0x00FFFF00, 0xFE8002FF);
+    DO_MIPS32_r(subu, 59, 0xFF0000FF, 0x01FFFF80, 0xFD00017F);
+    DO_MIPS32_r(subu, 60, 0xFE00007F, 0x03FFFFC0, 0xFA0000BF);
+    DO_MIPS32_r(subu, 61, 0xFC00003F, 0x07FFFFE0, 0xF400005F);
+    DO_MIPS32_r(subu, 62, 0xF800001F, 0x0FFFFFF0, 0xE800002F);
+    DO_MIPS32_r(subu, 63, 0xF000000F, 0x1FFFFFF8, 0xD0000017);
+    DO_MIPS32_r(subu, 64, 0xE0000007, 0x3FFFFFFC, 0xA000000B);
+    DO_MIPS32_r(subu, 65, 0xC0000003, 0x7FFFFFFE, 0x40000005);
+    DO_MIPS32_r(subu, 66, 0x80000001, 0xFFFFFFFF, 0x80000002);
+    DO_MIPS32_r(subu, 67, 0x00000000, 0xFFFFFFFF, 0x00000001);
+    DO_MIPS32_r(subu, 68, 0x00000000, 0x55555555, 0xAAAAAAAB);
+    DO_MIPS32_r(subu, 69, 0x55555555, 0x55555555, 0x00000000);
+    DO_MIPS32_r(subu, 70, 0xAAAAAAAA, 0x55555555, 0x55555555);
+    DO_MIPS32_r(subu, 71, 0xFFFFFFFF, 0x55555555, 0xAAAAAAAA);
+    DO_MIPS32_r(subu, 72, 0xAAAAAAAA, 0x00000000, 0xAAAAAAAA);
+    DO_MIPS32_r(subu, 73, 0xAAAAAAAA, 0x55555555, 0x55555555);
+    DO_MIPS32_r(subu, 74, 0xAAAAAAAA, 0xAAAAAAAA, 0x00000000);
+    DO_MIPS32_r(subu, 75, 0xAAAAAAAA, 0xFFFFFFFF, 0xAAAAAAAB);
+    DO_MIPS32_r(subu, 76, 0x7FFFFFFF, 0xFFFFFFFF, 0x80000000);
+    DO_MIPS32_r(subu, 77, 0x7FFFFFFF, 0x80000000, 0xFFFFFFFF);
+    DO_MIPS32_r(subu, 78, 0x80000000, 0x00000001, 0x7FFFFFFF);
+    DO_MIPS32_r(subu, 79, 0x80000000, 0x7FFFFFFF, 0x00000001);
+
+    printf("%s: PASS: %d, FAIL: %d\n", __FILE__, pass_count, fail_count);
+
+    if (fail_count) {
+        ret = -1;
+    }
+
+    return ret;
+}
-- 
2.34.1



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

* Re: [RFC PATCH 0/3] MIPS decodetree conversion attempt
  2022-09-21 12:41 [RFC PATCH 0/3] MIPS decodetree conversion attempt Jiaxun Yang
                   ` (2 preceding siblings ...)
  2022-09-21 12:41 ` [RFC PATCH 3/3] tests/tcg/mips: Add mips32 arithmatic instruction test cases Jiaxun Yang
@ 2022-09-26 14:44 ` Jiaxun Yang
  2022-09-26 21:35   ` Philippe Mathieu-Daudé via
  3 siblings, 1 reply; 8+ messages in thread
From: Jiaxun Yang @ 2022-09-26 14:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: Philippe Mathieu-Daudé, richard.henderson



> 2022年9月21日 13:41,Jiaxun Yang <jiaxun.yang@flygoat.com> 写道:
> 
> Hi,
> 
> This is my attempt of converting MIPS translation code into decodetree.
> 
> Currently only MIPS I to MIPS Release 5 arithmatic functions are converted.
> Old decoding functions are perserved in codebase for now due to dependencies
> from microMIPS/nanoMIPS translation code. Will remove them after dealing with
> release 6.
> 
> Both instruction encoding and test cases are generated form MIPS's internal
> architecture validation tools so they are gureented to be correct.

A kindly ping :-)

Will send v1 tomorrow if no objection.

Thanks
- Jiaxun

> 
> Thanks.
> 
> - Jiaxun
> 
> Jiaxun Yang (3):
>  target/mips: Introduce register access helper functions
>  target/mips: Convert legacy arithmatic instructions to decodetree
>  tests/tcg/mips: Add mips32 arithmatic instruction test cases
> 
> target/mips/tcg/insn_trans/trans_arith.c.inc  | 352 ++++++++++++++++++
> target/mips/tcg/legacy.decode                 |  62 +++
> target/mips/tcg/meson.build                   |   1 +
> target/mips/tcg/translate.c                   | 143 ++++++-
> target/mips/tcg/translate.h                   |  54 +++
> tests/tcg/mips/include/test_utils_32.h        |  75 ++++
> .../tcg/mips/user/isa/mips32/arithmatic/add.c |  99 +++++
> .../mips/user/isa/mips32/arithmatic/addi.c    |  70 ++++
> .../mips/user/isa/mips32/arithmatic/addiu.c   |  90 +++++
> .../mips/user/isa/mips32/arithmatic/addu.c    | 125 +++++++
> .../tcg/mips/user/isa/mips32/arithmatic/div.c |  81 ++++
> .../mips/user/isa/mips32/arithmatic/divu.c    |  78 ++++
> .../mips/user/isa/mips32/arithmatic/madd.c    |  79 ++++
> .../mips/user/isa/mips32/arithmatic/maddu.c   |  78 ++++
> .../mips/user/isa/mips32/arithmatic/msub.c    |  78 ++++
> .../mips/user/isa/mips32/arithmatic/msubu.c   |  78 ++++
> .../tcg/mips/user/isa/mips32/arithmatic/mul.c |  78 ++++
> .../mips/user/isa/mips32/arithmatic/mult.c    |  78 ++++
> .../mips/user/isa/mips32/arithmatic/multu.c   |  78 ++++
> .../tcg/mips/user/isa/mips32/arithmatic/slt.c |  61 +++
> .../mips/user/isa/mips32/arithmatic/slti.c    |  48 +++
> .../mips/user/isa/mips32/arithmatic/sltiu.c   |  48 +++
> .../mips/user/isa/mips32/arithmatic/sltu.c    |  61 +++
> .../tcg/mips/user/isa/mips32/arithmatic/sub.c | 104 ++++++
> .../mips/user/isa/mips32/arithmatic/subu.c    | 108 ++++++
> 25 files changed, 2206 insertions(+), 1 deletion(-)
> create mode 100644 target/mips/tcg/insn_trans/trans_arith.c.inc
> create mode 100644 target/mips/tcg/legacy.decode
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/add.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addi.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addiu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/div.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/divu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/madd.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/maddu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msub.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msubu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mul.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mult.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/multu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slt.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slti.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltiu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sub.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/subu.c
> 
> -- 
> 2.34.1
> 

---
Jiaxun Yang



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

* Re: [RFC PATCH 0/3] MIPS decodetree conversion attempt
  2022-09-26 14:44 ` [RFC PATCH 0/3] MIPS decodetree conversion attempt Jiaxun Yang
@ 2022-09-26 21:35   ` Philippe Mathieu-Daudé via
  2022-09-27 10:33     ` Jiaxun Yang
  0 siblings, 1 reply; 8+ messages in thread
From: Philippe Mathieu-Daudé via @ 2022-09-26 21:35 UTC (permalink / raw)
  To: Jiaxun Yang; +Cc: qemu-devel@nongnu.org Developers, Richard Henderson

Hi Jiaxun,

On Mon, Sep 26, 2022 at 4:44 PM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
> > 2022年9月21日 13:41,Jiaxun Yang <jiaxun.yang@flygoat.com> 写道:
> >
> > Hi,
> >
> > This is my attempt of converting MIPS translation code into decodetree.
> >
> > Currently only MIPS I to MIPS Release 5 arithmatic functions are converted.
> > Old decoding functions are perserved in codebase for now due to dependencies
> > from microMIPS/nanoMIPS translation code. Will remove them after dealing with
> > release 6.
> >
> > Both instruction encoding and test cases are generated form MIPS's internal
> > architecture validation tools so they are gureented to be correct.
>
> A kindly ping :-)
>
> Will send v1 tomorrow if no objection.

Thanks for this work! On a first pass it looks good, but I'd like to
spend more time reviewing in the next few days. What did you change
between RFC->v1?


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

* Re: [RFC PATCH 0/3] MIPS decodetree conversion attempt
  2022-09-26 21:35   ` Philippe Mathieu-Daudé via
@ 2022-09-27 10:33     ` Jiaxun Yang
  2022-10-06 13:37       ` Jiaxun Yang
  0 siblings, 1 reply; 8+ messages in thread
From: Jiaxun Yang @ 2022-09-27 10:33 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: qemu-devel@nongnu.org Developers, Richard Henderson



> 2022年9月26日 22:35,Philippe Mathieu-Daudé <f4bug@amsat.org> 写道:
> 
> Hi Jiaxun,
> 
> On Mon, Sep 26, 2022 at 4:44 PM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
>>> 2022年9月21日 13:41,Jiaxun Yang <jiaxun.yang@flygoat.com> 写道:
>>> 
>>> Hi,
>>> 
>>> This is my attempt of converting MIPS translation code into decodetree.
>>> 
>>> Currently only MIPS I to MIPS Release 5 arithmatic functions are converted.
>>> Old decoding functions are perserved in codebase for now due to dependencies
>>> from microMIPS/nanoMIPS translation code. Will remove them after dealing with
>>> release 6.
>>> 
>>> Both instruction encoding and test cases are generated form MIPS's internal
>>> architecture validation tools so they are gureented to be correct.
>> 
>> A kindly ping :-)
>> 
>> Will send v1 tomorrow if no objection.
> 
> Thanks for this work! On a first pass it looks good, but I'd like to
> spend more time reviewing in the next few days. What did you change
> between RFC->v1?

Nothing much, just tidy up test cases a little bit.

Thanks.
---
Jiaxun Yang



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

* Re: [RFC PATCH 0/3] MIPS decodetree conversion attempt
  2022-09-27 10:33     ` Jiaxun Yang
@ 2022-10-06 13:37       ` Jiaxun Yang
  0 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2022-10-06 13:37 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: qemu-devel@nongnu.org Developers, Richard Henderson



> 2022年9月27日 11:33,Jiaxun Yang <jiaxun.yang@flygoat.com> 写道:
> 
> 
> 
>> 2022年9月26日 22:35,Philippe Mathieu-Daudé <f4bug@amsat.org> 写道:
>> 
>> Hi Jiaxun,
>> 
>> On Mon, Sep 26, 2022 at 4:44 PM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
>>>> 2022年9月21日 13:41,Jiaxun Yang <jiaxun.yang@flygoat.com> 写道:
>>>> 
>>>> Hi,
>>>> 
>>>> This is my attempt of converting MIPS translation code into decodetree.
>>>> 
>>>> Currently only MIPS I to MIPS Release 5 arithmatic functions are converted.
>>>> Old decoding functions are perserved in codebase for now due to dependencies
>>>> from microMIPS/nanoMIPS translation code. Will remove them after dealing with
>>>> release 6.
>>>> 
>>>> Both instruction encoding and test cases are generated form MIPS's internal
>>>> architecture validation tools so they are gureented to be correct.
>>> 
>>> A kindly ping :-)
>>> 
>>> Will send v1 tomorrow if no objection.
>> 
>> Thanks for this work! On a first pass it looks good, but I'd like to
>> spend more time reviewing in the next few days. What did you change
>> between RFC->v1?
> 
> Nothing much, just tidy up test cases a little bit.

Any inputs?

Thanks.

> 
> Thanks.
> ---
> Jiaxun Yang
> 
> 

---
Jiaxun Yang



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

end of thread, other threads:[~2022-10-06 13:40 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-21 12:41 [RFC PATCH 0/3] MIPS decodetree conversion attempt Jiaxun Yang
2022-09-21 12:41 ` [RFC PATCH 1/3] target/mips: Introduce register access helper functions Jiaxun Yang
2022-09-21 12:41 ` [RFC PATCH 2/3] target/mips: Convert legacy arithmatic instructions to decodetree Jiaxun Yang
2022-09-21 12:41 ` [RFC PATCH 3/3] tests/tcg/mips: Add mips32 arithmatic instruction test cases Jiaxun Yang
2022-09-26 14:44 ` [RFC PATCH 0/3] MIPS decodetree conversion attempt Jiaxun Yang
2022-09-26 21:35   ` Philippe Mathieu-Daudé via
2022-09-27 10:33     ` Jiaxun Yang
2022-10-06 13:37       ` Jiaxun Yang

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